如何使用 UIDefault 为 swing 创建新的外观
How use UIDefault for create new look and feel for swing
我正在为 Java 开发新的外观和感觉;这种外观导入了 Material 风格。
我曾使用 UIDefault 导入外观内部的更改,所以现在我必须卸载外观,但此操作出现问题。
外观和感觉没有正确删除,现在我已经将 UIDefault 映射用于所有操作,我认为这是一个错误,因为我的常量覆盖了旧常量并且当我去删除我的外观和感觉时。新的外观和感觉不会覆盖我的常量
这就是我使用 UIDefault
的方式
@Override
protected void initComponentDefaults(UIDefaults table) {
super.initComponentDefaults(table);
table.put("Button.highlight", MaterialColors.GRAY_400);
table.put("Button.opaque", false);
table.put("Button.border", BorderFactory.createEmptyBorder(7, 17, 7, 17));
table.put("Button.background", MaterialColors.GRAY_200);
table.put("Button.foreground", MaterialColors.COSMO_BLACK);
table.put("Button.disabledBackground", MaterialColors.COSMO_DARK_GRAY);
table.put("Button.disabledForeground", MaterialColors.BLACK);
table.put("Button[Default].background", MaterialColors.LIGHT_BLUE_500);
table.put("Button[Default].foreground", Color.WHITE);
table.put("Button.font", MaterialFontFactory.getInstance().getFont(MaterialFontFactory.BOLD));
//table.put("Button[Default].mouseHoverColor", MaterialColors.LIGHT_BLUE_200);
table.put("Button.mouseHoverColor", MaterialColors.GRAY_500);
table.put("Button.mouseHoverEnable", true);
table.put("Button.focusable", true);
table.put("Button[focus].color", MaterialColors.GRAY_900);
table.put("Button.disabledText", MaterialColors.GRAY_600);
table.put("CheckBox.font", MaterialFontFactory.getInstance().getFont(MaterialFontFactory.BOLD));
table.put("CheckBox.background", MaterialColors.WHITE);
table.put("CheckBox.foreground", MaterialColors.BLACK);
table.put("CheckBox.disabledText", MaterialColors.COSMO_STRONG_GRAY);
table.put("CheckBox.icon", new ImageIcon(MaterialImageFactory.getInstance().getImage(MaterialImageFactory.UNCHECKED_BLACK_BOX)));
table.put("CheckBox.selectedIcon", new ImageIcon(MaterialImageFactory.getInstance().getImage(MaterialImageFactory.CHECKED_BLACK_BOX)));
table.put("ComboBox.font", MaterialFontFactory.getInstance().getFont(MaterialFontFactory.REGULAR));
table.put("ComboBox.background", MaterialColors.WHITE);
table.put("ComboBox.foreground", MaterialColors.BLACK);
table.put("ComboBox.border", MaterialBorders.roundedLineColorBorder(MaterialColors.COSMO_BLACK));
table.put("ComboBox.borderItems", BorderFactory.createEmptyBorder(1, 2, 0, 1));
table.put("ComboBox.buttonBackground", MaterialColors.WHITE);
table.put("ComboBox[button].border", BorderFactory.createLineBorder(MaterialColors.WHITE));
table.put("ComboBox.disabledBackground", MaterialColors.WHITE);
table.put("ComboBox.disabledForeground", MaterialColors.GRAY_900);
table.put("ComboBox.selectionBackground", MaterialColors.WHITE);
table.put("ComboBox.selectionForeground", Color.BLACK);
table.put("ComboBox.selectedInDropDownBackground", MaterialColors.COSMO_LIGTH_BLUE);
table.put("ComboBox.mouseHoverColor", MaterialColors.WHITE);
table.put("ComboBox.unfocusColor", MaterialColors.COSMO_BLACK);
table.put("ComboBox.focusColor", MaterialColors.LIGHT_BLUE_400);
table.put("ComboBox.mouseHoverEnabled", false);
table.put("Menu.font", MaterialFontFactory.getInstance().getFont(MaterialFontFactory.REGULAR));
table.put("Menu.border", BorderFactory.createEmptyBorder(5, 5, 5, 5));
table.put("Menu.background", Color.WHITE);
table.put("Menu.foreground", Color.BLACK);
table.put("Menu.opaque", true);
table.put("Menu.selectionBackground", MaterialColors.GRAY_200);
table.put("Menu.selectionForeground", MaterialColors.BLACK);
table.put("Menu.disabledForeground", new Color(0, 0, 0, 100));
table.put("Menu.menuPopupOffsetY", 3);
table.put("Menu[MouseOver].enable", true); //TODO adding into master
table.put("MenuBar.font", MaterialFontFactory.getInstance().getFont(MaterialFontFactory.BOLD));
table.put("MenuBar.background", Color.WHITE);
table.put("MenuBar.border", MaterialBorders.LIGHT_SHADOW_BORDER);
table.put("MenuBar.foreground", MaterialColors.BLACK);
table.put("MenuItem.disabledForeground", new Color(0, 0, 0, 100));
table.put("MenuItem.selectionBackground", MaterialColors.GRAY_200);
table.put("MenuItem.selectionForeground", Color.BLACK);
table.put("MenuItem.font", MaterialFontFactory.getInstance().getFont(MaterialFontFactory.MEDIUM));
table.put("MenuItem.background", Color.WHITE);
table.put("MenuItem.foreground", Color.BLACK);
table.put("MenuItem.border", BorderFactory.createEmptyBorder(5, 0, 5, 0));
}
这是我的应用程序,具有我的外观和感觉
这是我更改外观时的应用
这是更改外观的代码
public class DemoGUITest extends JFrame {
static {
try {
UIManager.setLookAndFeel(new MaterialLookAndFeel());
JDialog.setDefaultLookAndFeelDecorated(true);
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
private static final DemoGUITest SINGLETON = new DemoGUITest();
public void reloadUI(){
SwingUtilities.updateComponentTreeUI(this);
}
public void changeThemeWith(BasicLookAndFeel lookAndFeel){
try {
UIManager.setLookAndFeel(lookAndFeel);
this.reloadUI();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SINGLETON.initComponent();
}
});
}
}
这是一个最小的例子
Class主要
import com.sun.java.swing.plaf.gtk.GTKLookAndFeel;
import mdlaf.utils.MaterialColors;
import mdlaf.utils.MaterialFontFactory;
import javax.swing.*;
import javax.swing.plaf.BorderUIResource;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.metal.MetalLookAndFeel;
import java.awt.*;
import java.awt.event.ActionEvent;
/**
* @author https://github.com/vincenzopalazzo
*/
public class MaterialMain extends JFrame {
public static MaterialMain SINGLETON = new MaterialMain();
static {
try {
UIManager.setLookAndFeel(new LookAndFeelTest());
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
public void init() {
JMenuBar menuBar = new JMenuBar();
JMenu file = new JMenu("File");
menuBar.add(file);
this.setJMenuBar(menuBar);
JPanel panel = new JPanel();
JButton changeTheme = new JButton();
changeTheme.setAction(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
try {
UIManager.setLookAndFeel(new GTKLookAndFeel());
} catch (UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
SwingUtilities.updateComponentTreeUI(SINGLETON);
}
});
changeTheme.setText("Set GTK");
panel.add(changeTheme);
setTitle("Look and feel");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(630, 360);
add(panel);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SINGLETON.init();
}
});
}
public static class LookAndFeelTest extends MetalLookAndFeel{
@Override
protected void initClassDefaults(UIDefaults table) {
super.initClassDefaults(table);
table.put("MenuUI", MenuTestUI.class.getCanonicalName());
table.put("ButtonUI", JButtonUI.class.getCanonicalName());
}
@Override
protected void initComponentDefaults(UIDefaults table) {
super.initComponentDefaults(table);
//table.put("Menu.font", new FontUIResource(MaterialFontFactory.getInstance().getFont(MaterialFontFactory.REGULAR)));
table.put("Menu.border", new BorderUIResource(BorderFactory.createEmptyBorder(5, 5, 5, 5)));
table.put("Menu.background", (Color.ORANGE));
table.put("Menu.foreground", (Color.BLACK));
table.put("Menu.opaque", true);
table.put("Menu.selectionBackground", new ColorUIResource(Color.YELLOW));
table.put("Menu.selectionForeground", new ColorUIResource(Color.BLACK));
table.put("Menu.disabledForeground", new ColorUIResource(new Color(0, 0, 0, 100)));
table.put("Menu.menuPopupOffsetY", 3);
//table.put("MenuBar.font", MaterialFontFactory.getInstance().getFont(MaterialFontFactory.BOLD));
table.put("MenuBar.background", (Color.ORANGE));
//table.put("MenuBar.border", MaterialBorders.LIGHT_SHADOW_BORDER);
table.put("MenuBar.foreground", (Color.BLACK));
table.put("Button.highlight", Color.ORANGE);
table.put("Button.opaque", false);
table.put("Button.border", BorderFactory.createEmptyBorder(7, 17, 7, 17));
table.put("Button.background", Color.ORANGE);
table.put("Button.foreground", Color.BLACK);
table.put("Button.focusable", true);
table.put("Button[focus].color", Color.GREEN);
}
}
}
菜单界面
import mdlaf.animation.MaterialUIMovement;
import mdlaf.components.menu.MaterialMenuUI;
import mdlaf.utils.MaterialManagerListener;
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicMenuUI;
import java.awt.*;
/**
* @author https://github.com/vincenzopalazzo
*/
public class MenuTestUI extends BasicMenuUI {
public static ComponentUI createUI (JComponent c) {
return new MaterialMenuUI();
}
@Override
public void installUI (JComponent c) {
super.installUI (c);
JMenu menu = (JMenu) c;
menu.setFont (UIManager.getFont ("Menu.font"));
menu.setBorder (UIManager.getBorder ("Menu.border"));
menu.setBackground (UIManager.getColor ("Menu.background"));
menu.setForeground (UIManager.getColor ("Menu.foreground"));
menu.setOpaque (UIManager.getBoolean ("Menu.opaque"));
c.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
@Override
public void uninstallUI(JComponent c) {
menuItem.setFont (null);
menuItem.setBackground (null);
menuItem.setForeground (null);
menuItem.setBorder (null);
menuItem.setCursor(null);
MaterialManagerListener.removeAllMaterialMouseListener(menuItem);
super.uninstallUI(menuItem);
}
}
按钮UI
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicButtonUI;
import java.awt.*;
/**
* @author https://github.com/vincenzopalazzo
*/
public class JButtonUI extends BasicButtonUI {
public static final String UI_KEY = "ButtonUI";
public static ComponentUI createUI(final JComponent c) {
return new JButtonUI();
}
private AbstractButton button;
private Color foreground;
private Color background;
private Color disabledBackground;
private Color disabledForeground;
private Color defaultBackground;
private Color defaultForeground;
private Boolean isDefaultButton = null;
@Override
public void installUI(JComponent c) {
super.installUI(c);
AbstractButton button = (AbstractButton) c;
button.setOpaque(UIManager.getBoolean("Button.opaque"));
button.setBorder(UIManager.getBorder("Button.border"));
foreground = UIManager.getColor("Button.foreground");
background = UIManager.getColor("Button.background");
disabledBackground = UIManager.getColor("Button.disabledBackground");
disabledForeground = UIManager.getColor("Button.disabledForeground");
defaultBackground = UIManager.getColor("Button[Default].background");
defaultForeground = UIManager.getColor("Button[Default].foreground");
button.setBackground(background);
button.setForeground(foreground);
button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
button.setFocusable(UIManager.getBoolean("Button.focusable"));
this.button = button;
}
@Override
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
AbstractButton button = (AbstractButton) c;
button.setBorder(null);
foreground = null;
background = null;
disabledBackground = null;
disabledForeground = null;
defaultBackground = null;
defaultForeground = null;
button.setBackground(null);
button.setForeground(null);
button.setCursor(null);
}
@Override
public void paint(Graphics g, JComponent c) {
JButton b = (JButton) c;
if (b.isContentAreaFilled()) {
paintBackground(g, b);
}
if (isDefaultButton == null && b.isEnabled()) {
isDefaultButton = ((JButton) button).isDefaultButton();
if (isDefaultButton) {
paintStateButton(c, g);
}
}
super.paint(g, c);
}
private void paintBackground(Graphics g, JComponent c) {
Graphics2D graphics = (Graphics2D) g.create();
g.setColor(c.getBackground());
JButton b = (JButton) c;
if (!UIManager.getBoolean("Button[border].toAll") && (button.getIcon() != null)) {
g.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), 7, 7);
} else {
g.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), 7, 7);
if (isDefaultButton != null && isDefaultButton) {
g.setColor(UIManager.getColor("Button[Default].background"));
if(UIManager.getBoolean("Button[Default].shadowEnable")){
paintShadow(g, button);
}
return;
}
if(UIManager.getBoolean("Button[border].enable")){
paintBorderButton(graphics, b);
}
}
paintStateButton(c, g);
}
@Override
protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect, Rectangle textRect, Rectangle iconRect) {
// driveLine(g, (JButton) b);
paintFocusRing(g, (JButton) b);
//paintShadow(MaterialDrawingUtils.getAliasedGraphics(g), button);
}
@Override
public void update(Graphics g, JComponent c) {
super.update(g, c);
//c.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
@Override
protected void paintButtonPressed(Graphics g, AbstractButton b) {
g.fillRoundRect(0, 0, b.getWidth(), b.getHeight(), 7, 7);
}
protected void paintFocusRing(Graphics g, JButton b) {
Stroke dashed = new BasicStroke(1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f, new float[]{0f, 3f}, 10.0f);
//Stroke dashed = new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{9}, 0);
Graphics2D g2 = (Graphics2D) g.create();
g2.setStroke(dashed);
if (isDefaultButton) {
g2.setColor(UIManager.getColor("Button[Default][focus].color"));
} else {
g2.setColor(UIManager.getColor("Button[focus].color"));
}
g2.drawRoundRect(5, 5, b.getWidth() - 10, b.getHeight() - 10, 7, 7);
g2.dispose();
}
protected void paintShadow(Graphics g, JComponent c) {
int topOpacity = 80;
int pixels = UIManager.getInt("Button[Default].shadowPixel");
JButton b = (JButton) c;
int valueRed = 255;
int valueGreen = 255;
int valueBlue = 255;
for (int i = pixels; i >= 0; i--) {
if(valueBlue > 70){
valueRed -= 70;
valueGreen -= 70;
valueBlue -= 70;
}else{
valueBlue -= valueBlue;
valueGreen -= valueGreen;
valueRed -= valueRed;
}
Color result = new Color(valueRed, valueGreen, valueBlue, topOpacity);
g.setColor(result);
g.drawRoundRect(i, i, b.getWidth() - ((i * 2) + 1), b.getHeight() - ((i * 2) + 1), 7, 7);
}
}
protected void paintBorderButton(Graphics2D graphics, JButton b) {
graphics.setStroke(new BasicStroke(2f));
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int w = b.getWidth() - 1;
int h = b.getHeight() - 1;
int arc = 7;
graphics.setColor(UIManager.getColor("Button[border].color"));
graphics.drawRoundRect(0, 0, w, h, arc, arc);
}
protected void paintStateButton(JComponent component, Graphics graphics) {
if (component == null || graphics == null) {
throw new IllegalArgumentException("Input null");
}
JButton b = (JButton) component;
if (b.isEnabled() && (isDefaultButton != null && isDefaultButton) && !b.isSelected()) {
//MaterialManagerListener.removeAllMaterialMouseListener(b);
//b.addMouseListener(MaterialUIMovement.getMovement(b, MaterialColors.LIGHT_BLUE_100));
b.setBackground(defaultBackground);
b.setForeground(defaultForeground);
return;
}
if (!b.isEnabled()) {
b.setBackground(disabledBackground);
b.setForeground(disabledForeground);
return;
}
}
}
但是即使我复制了我的代码,这段代码也没有重现问题;错误的演示是 here
我想问问你是不是上述那个问题,特别是如果我用错了 UIDefault
这可能是您使用 L&F 的问题。您放入 UIManager
中的所有资源(原语除外)都必须是 javax.swing.plaf.UIResource
接口的实例。 Swing 提供了一些预定义的 类,例如 ColorUIResource
、BorderUIResource
、IconUIResource
等,您可以在代码中使用它们。
为什么需要它?这个界面告诉下一个 Look-n-Feel 这个设置可以在它应用它的设置时改变。
代码示例:
table.put("OptionPane.warningDialog.titlePane.shadow", new ColorUIResource(MaterialColors.COSMO_STRONG_GRAY));
table.put("FormattedTextField.border", new BorderUIResource(BorderFactory.createEmptyBorder(3, 5, 2, 5)));
table.put("List.font", new FontUIResource(MaterialFontFactory.getInstance().getFont(MaterialFontFactory.MEDIUM)));
如果您的工厂以 UIResource 实例的形式提供资源,可能会更好。
重要
当我的建议不能帮助您解决问题时,请提供一个Minimal, Reproducible Example,以便我们更好地了解问题所在,也可以调试您的代码以提供适合您的情况的解决方案。
我正在为 Java 开发新的外观和感觉;这种外观导入了 Material 风格。
我曾使用 UIDefault 导入外观内部的更改,所以现在我必须卸载外观,但此操作出现问题。
外观和感觉没有正确删除,现在我已经将 UIDefault 映射用于所有操作,我认为这是一个错误,因为我的常量覆盖了旧常量并且当我去删除我的外观和感觉时。新的外观和感觉不会覆盖我的常量
这就是我使用 UIDefault
的方式@Override
protected void initComponentDefaults(UIDefaults table) {
super.initComponentDefaults(table);
table.put("Button.highlight", MaterialColors.GRAY_400);
table.put("Button.opaque", false);
table.put("Button.border", BorderFactory.createEmptyBorder(7, 17, 7, 17));
table.put("Button.background", MaterialColors.GRAY_200);
table.put("Button.foreground", MaterialColors.COSMO_BLACK);
table.put("Button.disabledBackground", MaterialColors.COSMO_DARK_GRAY);
table.put("Button.disabledForeground", MaterialColors.BLACK);
table.put("Button[Default].background", MaterialColors.LIGHT_BLUE_500);
table.put("Button[Default].foreground", Color.WHITE);
table.put("Button.font", MaterialFontFactory.getInstance().getFont(MaterialFontFactory.BOLD));
//table.put("Button[Default].mouseHoverColor", MaterialColors.LIGHT_BLUE_200);
table.put("Button.mouseHoverColor", MaterialColors.GRAY_500);
table.put("Button.mouseHoverEnable", true);
table.put("Button.focusable", true);
table.put("Button[focus].color", MaterialColors.GRAY_900);
table.put("Button.disabledText", MaterialColors.GRAY_600);
table.put("CheckBox.font", MaterialFontFactory.getInstance().getFont(MaterialFontFactory.BOLD));
table.put("CheckBox.background", MaterialColors.WHITE);
table.put("CheckBox.foreground", MaterialColors.BLACK);
table.put("CheckBox.disabledText", MaterialColors.COSMO_STRONG_GRAY);
table.put("CheckBox.icon", new ImageIcon(MaterialImageFactory.getInstance().getImage(MaterialImageFactory.UNCHECKED_BLACK_BOX)));
table.put("CheckBox.selectedIcon", new ImageIcon(MaterialImageFactory.getInstance().getImage(MaterialImageFactory.CHECKED_BLACK_BOX)));
table.put("ComboBox.font", MaterialFontFactory.getInstance().getFont(MaterialFontFactory.REGULAR));
table.put("ComboBox.background", MaterialColors.WHITE);
table.put("ComboBox.foreground", MaterialColors.BLACK);
table.put("ComboBox.border", MaterialBorders.roundedLineColorBorder(MaterialColors.COSMO_BLACK));
table.put("ComboBox.borderItems", BorderFactory.createEmptyBorder(1, 2, 0, 1));
table.put("ComboBox.buttonBackground", MaterialColors.WHITE);
table.put("ComboBox[button].border", BorderFactory.createLineBorder(MaterialColors.WHITE));
table.put("ComboBox.disabledBackground", MaterialColors.WHITE);
table.put("ComboBox.disabledForeground", MaterialColors.GRAY_900);
table.put("ComboBox.selectionBackground", MaterialColors.WHITE);
table.put("ComboBox.selectionForeground", Color.BLACK);
table.put("ComboBox.selectedInDropDownBackground", MaterialColors.COSMO_LIGTH_BLUE);
table.put("ComboBox.mouseHoverColor", MaterialColors.WHITE);
table.put("ComboBox.unfocusColor", MaterialColors.COSMO_BLACK);
table.put("ComboBox.focusColor", MaterialColors.LIGHT_BLUE_400);
table.put("ComboBox.mouseHoverEnabled", false);
table.put("Menu.font", MaterialFontFactory.getInstance().getFont(MaterialFontFactory.REGULAR));
table.put("Menu.border", BorderFactory.createEmptyBorder(5, 5, 5, 5));
table.put("Menu.background", Color.WHITE);
table.put("Menu.foreground", Color.BLACK);
table.put("Menu.opaque", true);
table.put("Menu.selectionBackground", MaterialColors.GRAY_200);
table.put("Menu.selectionForeground", MaterialColors.BLACK);
table.put("Menu.disabledForeground", new Color(0, 0, 0, 100));
table.put("Menu.menuPopupOffsetY", 3);
table.put("Menu[MouseOver].enable", true); //TODO adding into master
table.put("MenuBar.font", MaterialFontFactory.getInstance().getFont(MaterialFontFactory.BOLD));
table.put("MenuBar.background", Color.WHITE);
table.put("MenuBar.border", MaterialBorders.LIGHT_SHADOW_BORDER);
table.put("MenuBar.foreground", MaterialColors.BLACK);
table.put("MenuItem.disabledForeground", new Color(0, 0, 0, 100));
table.put("MenuItem.selectionBackground", MaterialColors.GRAY_200);
table.put("MenuItem.selectionForeground", Color.BLACK);
table.put("MenuItem.font", MaterialFontFactory.getInstance().getFont(MaterialFontFactory.MEDIUM));
table.put("MenuItem.background", Color.WHITE);
table.put("MenuItem.foreground", Color.BLACK);
table.put("MenuItem.border", BorderFactory.createEmptyBorder(5, 0, 5, 0));
}
这是我的应用程序,具有我的外观和感觉
这是我更改外观时的应用
这是更改外观的代码
public class DemoGUITest extends JFrame {
static {
try {
UIManager.setLookAndFeel(new MaterialLookAndFeel());
JDialog.setDefaultLookAndFeelDecorated(true);
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
private static final DemoGUITest SINGLETON = new DemoGUITest();
public void reloadUI(){
SwingUtilities.updateComponentTreeUI(this);
}
public void changeThemeWith(BasicLookAndFeel lookAndFeel){
try {
UIManager.setLookAndFeel(lookAndFeel);
this.reloadUI();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SINGLETON.initComponent();
}
});
}
}
这是一个最小的例子
Class主要
import com.sun.java.swing.plaf.gtk.GTKLookAndFeel;
import mdlaf.utils.MaterialColors;
import mdlaf.utils.MaterialFontFactory;
import javax.swing.*;
import javax.swing.plaf.BorderUIResource;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.metal.MetalLookAndFeel;
import java.awt.*;
import java.awt.event.ActionEvent;
/**
* @author https://github.com/vincenzopalazzo
*/
public class MaterialMain extends JFrame {
public static MaterialMain SINGLETON = new MaterialMain();
static {
try {
UIManager.setLookAndFeel(new LookAndFeelTest());
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
public void init() {
JMenuBar menuBar = new JMenuBar();
JMenu file = new JMenu("File");
menuBar.add(file);
this.setJMenuBar(menuBar);
JPanel panel = new JPanel();
JButton changeTheme = new JButton();
changeTheme.setAction(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
try {
UIManager.setLookAndFeel(new GTKLookAndFeel());
} catch (UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
SwingUtilities.updateComponentTreeUI(SINGLETON);
}
});
changeTheme.setText("Set GTK");
panel.add(changeTheme);
setTitle("Look and feel");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(630, 360);
add(panel);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
SINGLETON.init();
}
});
}
public static class LookAndFeelTest extends MetalLookAndFeel{
@Override
protected void initClassDefaults(UIDefaults table) {
super.initClassDefaults(table);
table.put("MenuUI", MenuTestUI.class.getCanonicalName());
table.put("ButtonUI", JButtonUI.class.getCanonicalName());
}
@Override
protected void initComponentDefaults(UIDefaults table) {
super.initComponentDefaults(table);
//table.put("Menu.font", new FontUIResource(MaterialFontFactory.getInstance().getFont(MaterialFontFactory.REGULAR)));
table.put("Menu.border", new BorderUIResource(BorderFactory.createEmptyBorder(5, 5, 5, 5)));
table.put("Menu.background", (Color.ORANGE));
table.put("Menu.foreground", (Color.BLACK));
table.put("Menu.opaque", true);
table.put("Menu.selectionBackground", new ColorUIResource(Color.YELLOW));
table.put("Menu.selectionForeground", new ColorUIResource(Color.BLACK));
table.put("Menu.disabledForeground", new ColorUIResource(new Color(0, 0, 0, 100)));
table.put("Menu.menuPopupOffsetY", 3);
//table.put("MenuBar.font", MaterialFontFactory.getInstance().getFont(MaterialFontFactory.BOLD));
table.put("MenuBar.background", (Color.ORANGE));
//table.put("MenuBar.border", MaterialBorders.LIGHT_SHADOW_BORDER);
table.put("MenuBar.foreground", (Color.BLACK));
table.put("Button.highlight", Color.ORANGE);
table.put("Button.opaque", false);
table.put("Button.border", BorderFactory.createEmptyBorder(7, 17, 7, 17));
table.put("Button.background", Color.ORANGE);
table.put("Button.foreground", Color.BLACK);
table.put("Button.focusable", true);
table.put("Button[focus].color", Color.GREEN);
}
}
}
菜单界面
import mdlaf.animation.MaterialUIMovement;
import mdlaf.components.menu.MaterialMenuUI;
import mdlaf.utils.MaterialManagerListener;
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicMenuUI;
import java.awt.*;
/**
* @author https://github.com/vincenzopalazzo
*/
public class MenuTestUI extends BasicMenuUI {
public static ComponentUI createUI (JComponent c) {
return new MaterialMenuUI();
}
@Override
public void installUI (JComponent c) {
super.installUI (c);
JMenu menu = (JMenu) c;
menu.setFont (UIManager.getFont ("Menu.font"));
menu.setBorder (UIManager.getBorder ("Menu.border"));
menu.setBackground (UIManager.getColor ("Menu.background"));
menu.setForeground (UIManager.getColor ("Menu.foreground"));
menu.setOpaque (UIManager.getBoolean ("Menu.opaque"));
c.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
@Override
public void uninstallUI(JComponent c) {
menuItem.setFont (null);
menuItem.setBackground (null);
menuItem.setForeground (null);
menuItem.setBorder (null);
menuItem.setCursor(null);
MaterialManagerListener.removeAllMaterialMouseListener(menuItem);
super.uninstallUI(menuItem);
}
}
按钮UI
import javax.swing.*;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicButtonUI;
import java.awt.*;
/**
* @author https://github.com/vincenzopalazzo
*/
public class JButtonUI extends BasicButtonUI {
public static final String UI_KEY = "ButtonUI";
public static ComponentUI createUI(final JComponent c) {
return new JButtonUI();
}
private AbstractButton button;
private Color foreground;
private Color background;
private Color disabledBackground;
private Color disabledForeground;
private Color defaultBackground;
private Color defaultForeground;
private Boolean isDefaultButton = null;
@Override
public void installUI(JComponent c) {
super.installUI(c);
AbstractButton button = (AbstractButton) c;
button.setOpaque(UIManager.getBoolean("Button.opaque"));
button.setBorder(UIManager.getBorder("Button.border"));
foreground = UIManager.getColor("Button.foreground");
background = UIManager.getColor("Button.background");
disabledBackground = UIManager.getColor("Button.disabledBackground");
disabledForeground = UIManager.getColor("Button.disabledForeground");
defaultBackground = UIManager.getColor("Button[Default].background");
defaultForeground = UIManager.getColor("Button[Default].foreground");
button.setBackground(background);
button.setForeground(foreground);
button.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
button.setFocusable(UIManager.getBoolean("Button.focusable"));
this.button = button;
}
@Override
public void uninstallUI(JComponent c) {
super.uninstallUI(c);
AbstractButton button = (AbstractButton) c;
button.setBorder(null);
foreground = null;
background = null;
disabledBackground = null;
disabledForeground = null;
defaultBackground = null;
defaultForeground = null;
button.setBackground(null);
button.setForeground(null);
button.setCursor(null);
}
@Override
public void paint(Graphics g, JComponent c) {
JButton b = (JButton) c;
if (b.isContentAreaFilled()) {
paintBackground(g, b);
}
if (isDefaultButton == null && b.isEnabled()) {
isDefaultButton = ((JButton) button).isDefaultButton();
if (isDefaultButton) {
paintStateButton(c, g);
}
}
super.paint(g, c);
}
private void paintBackground(Graphics g, JComponent c) {
Graphics2D graphics = (Graphics2D) g.create();
g.setColor(c.getBackground());
JButton b = (JButton) c;
if (!UIManager.getBoolean("Button[border].toAll") && (button.getIcon() != null)) {
g.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), 7, 7);
} else {
g.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), 7, 7);
if (isDefaultButton != null && isDefaultButton) {
g.setColor(UIManager.getColor("Button[Default].background"));
if(UIManager.getBoolean("Button[Default].shadowEnable")){
paintShadow(g, button);
}
return;
}
if(UIManager.getBoolean("Button[border].enable")){
paintBorderButton(graphics, b);
}
}
paintStateButton(c, g);
}
@Override
protected void paintFocus(Graphics g, AbstractButton b, Rectangle viewRect, Rectangle textRect, Rectangle iconRect) {
// driveLine(g, (JButton) b);
paintFocusRing(g, (JButton) b);
//paintShadow(MaterialDrawingUtils.getAliasedGraphics(g), button);
}
@Override
public void update(Graphics g, JComponent c) {
super.update(g, c);
//c.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
@Override
protected void paintButtonPressed(Graphics g, AbstractButton b) {
g.fillRoundRect(0, 0, b.getWidth(), b.getHeight(), 7, 7);
}
protected void paintFocusRing(Graphics g, JButton b) {
Stroke dashed = new BasicStroke(1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f, new float[]{0f, 3f}, 10.0f);
//Stroke dashed = new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{9}, 0);
Graphics2D g2 = (Graphics2D) g.create();
g2.setStroke(dashed);
if (isDefaultButton) {
g2.setColor(UIManager.getColor("Button[Default][focus].color"));
} else {
g2.setColor(UIManager.getColor("Button[focus].color"));
}
g2.drawRoundRect(5, 5, b.getWidth() - 10, b.getHeight() - 10, 7, 7);
g2.dispose();
}
protected void paintShadow(Graphics g, JComponent c) {
int topOpacity = 80;
int pixels = UIManager.getInt("Button[Default].shadowPixel");
JButton b = (JButton) c;
int valueRed = 255;
int valueGreen = 255;
int valueBlue = 255;
for (int i = pixels; i >= 0; i--) {
if(valueBlue > 70){
valueRed -= 70;
valueGreen -= 70;
valueBlue -= 70;
}else{
valueBlue -= valueBlue;
valueGreen -= valueGreen;
valueRed -= valueRed;
}
Color result = new Color(valueRed, valueGreen, valueBlue, topOpacity);
g.setColor(result);
g.drawRoundRect(i, i, b.getWidth() - ((i * 2) + 1), b.getHeight() - ((i * 2) + 1), 7, 7);
}
}
protected void paintBorderButton(Graphics2D graphics, JButton b) {
graphics.setStroke(new BasicStroke(2f));
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int w = b.getWidth() - 1;
int h = b.getHeight() - 1;
int arc = 7;
graphics.setColor(UIManager.getColor("Button[border].color"));
graphics.drawRoundRect(0, 0, w, h, arc, arc);
}
protected void paintStateButton(JComponent component, Graphics graphics) {
if (component == null || graphics == null) {
throw new IllegalArgumentException("Input null");
}
JButton b = (JButton) component;
if (b.isEnabled() && (isDefaultButton != null && isDefaultButton) && !b.isSelected()) {
//MaterialManagerListener.removeAllMaterialMouseListener(b);
//b.addMouseListener(MaterialUIMovement.getMovement(b, MaterialColors.LIGHT_BLUE_100));
b.setBackground(defaultBackground);
b.setForeground(defaultForeground);
return;
}
if (!b.isEnabled()) {
b.setBackground(disabledBackground);
b.setForeground(disabledForeground);
return;
}
}
}
但是即使我复制了我的代码,这段代码也没有重现问题;错误的演示是 here
我想问问你是不是上述那个问题,特别是如果我用错了 UIDefault
这可能是您使用 L&F 的问题。您放入 UIManager
中的所有资源(原语除外)都必须是 javax.swing.plaf.UIResource
接口的实例。 Swing 提供了一些预定义的 类,例如 ColorUIResource
、BorderUIResource
、IconUIResource
等,您可以在代码中使用它们。
为什么需要它?这个界面告诉下一个 Look-n-Feel 这个设置可以在它应用它的设置时改变。
代码示例:
table.put("OptionPane.warningDialog.titlePane.shadow", new ColorUIResource(MaterialColors.COSMO_STRONG_GRAY));
table.put("FormattedTextField.border", new BorderUIResource(BorderFactory.createEmptyBorder(3, 5, 2, 5)));
table.put("List.font", new FontUIResource(MaterialFontFactory.getInstance().getFont(MaterialFontFactory.MEDIUM)));
如果您的工厂以 UIResource 实例的形式提供资源,可能会更好。
重要
当我的建议不能帮助您解决问题时,请提供一个Minimal, Reproducible Example,以便我们更好地了解问题所在,也可以调试您的代码以提供适合您的情况的解决方案。