摇摆:创建UWP(“新城”) - 就像按钮
我想设计一个Swing的按钮,看起来像一个UWP一个 - 像这样的[Windows设置应用程序]: 摇摆:创建UWP(“新城”) - 就像按钮
这是什么我至今:
使用下面的代码:
Font f = new Font("Segoe UI", Font.PLAIN, 20);
Color gray = new Color(204, 204, 204);
button.setFont(f);
button.setBackground(gray);
button.setContentAreaFilled(false);
button.setFocusPainted(false);
button.setFocusable(false);
button.setForeground(Color.BLACK);
button.setBorder(BorderFactory.createEmptyBorder(10, 14, 10, 14));
背景颜色不能在一切都变了,不管磨她的button.setContentAreaFilled(Boolean b);
属性设置为false
或true
,因为EmptyBorder
继承了Windows Swing按钮的默认颜色。
悬停(悬停时的颜色变化)也会停止以将属性设置为false
。
设置button.setContentAreaFilled(true);
给出了如下的结果,这也是不理想的,因为按钮的背景仍然没有从默认颜色改变(+它有一个轮廓):
我的问题是,基本上:如何修改我的代码以获得以下类似UWP的设计?
默认:
悬停:
下面是一个例子
import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import javax.swing.border.CompoundBorder;
import javax.swing.border.LineBorder;
public class WinButton {
public static void main(String[] args) {
final JButton button = createWinButton("Restart now");
JFrame frm = new JFrame("Test");
JPanel layoutPanel = new JPanel();
layoutPanel.add(button);
frm.add(layoutPanel);
frm.setSize(200, 200);
frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
private static JButton createWinButton(String text) {
final JButton button = new JButton(text);
Font f = new Font("Segoe UI", Font.PLAIN, 20);
Color gray = new Color(204, 204, 204);
button.setFont(f);
button.setBackground(gray);
button.setContentAreaFilled(false);
button.setFocusPainted(false);
button.setFocusable(false);
button.setForeground(Color.BLACK);
button.setOpaque(true);
button.setBorder(BorderFactory.createEmptyBorder(10, 14, 10, 14));
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
Color borderColor = new Color(100, 100, 100);
button.setBorder(new CompoundBorder(new LineBorder(borderColor, 3), BorderFactory.createEmptyBorder(7, 11, 7, 11)));
}
@Override
public void mouseExited(MouseEvent e) {
button.setBorder(BorderFactory.createEmptyBorder(10, 14, 10, 14));
}
});
return button;
}
}
为了操纵鼠标事件,如悬停,你”你必须对待这些事件如果要做的一个方法是创建你自己的按钮。
编辑
添加鼠标监听到你的按钮,由Sergiy Medvynskyy作为回答,会是一个更好的做法,因为没有必要与按钮类上做文章。
您也可以与拉芳玩(UIManager的外观),因为它可以增加不需要的效果,UI组件。
请注意,这可能会影响所有接口组件。
以下是一个基本示例。
按钮:
import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.border.Border;
public class UWPButton extends JButton{
private final Border regularBorder;
private final Border hoverBorder;
private final Color bgColor = new Color(204, 204, 204);
private final Color transparent;
private final Font metroFont = new Font("Segoe UI", Font.PLAIN, 20);
public UWPButton() {
super();
// thickness of the button's borders
int thickness = 4;
// Create a transparent color, to use for the regular border
// could also be the bgColor (204 204 204)
Color c = new Color(1f, 0f, 0f, 0f);
transparent = c;
// Creates a compound border to be present on the button majority of the time.
// uses an invisible line border on the outside in order to change border smoothly
// the inside border is just an empty border for insets.
regularBorder = BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(transparent, thickness), //outside
BorderFactory.createEmptyBorder(10, 14, 10, 14)); //inside
// Creates a compound border which will be used when the mouse hovers the button.
// the outside border has a darker colour than the background
// the inside border is just an empty border for insets.
hoverBorder = BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(bgColor.darker(), thickness), //outside
BorderFactory.createEmptyBorder(10, 14, 10, 14)); //inside
// configures the button
initButton();
}
// Here is where the mouse events are treated.
@Override
protected void processMouseEvent(MouseEvent e) {
// Gets the ID of the event,
// if it is a mouse entering the button, sets the new border
// if it is the mouse exiting the button, resets the border to the default.
switch(e.getID()){
case MouseEvent.MOUSE_ENTERED:
this.setBorder(hoverBorder);
break;
case MouseEvent.MOUSE_EXITED:
this.setBorder(regularBorder);
break;
}
// the parent then does all the other handling.
super.processMouseEvent(e);
}
// Configures the button.
private void initButton(){
setFont(metroFont);
setBorder(regularBorder);
setBackground(bgColor);
setFocusPainted(false);
}
}
改变拉芳:如果您通过IDE拖放创建了框架,你应该有这样的事情里面你的主(这是从NetBeans中):
CHANGE “Nimbus”改为“Metro”(或删除LaF设置),以便界面管理器不会渲染所有Nimbus内容。 注意:没有“Metro”LaF,这只是为了禁用应用的LaF。
// other stuff above
//
// change "Nimbus" for something else or just remove this try-catch block
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
// other stuff bellow
更多关于阿姆斯特朗基金会(外观): https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
有许多的方法,你“可能”做到这一点,你可以
- 创建一个工厂方法来申请您需要模拟功能的属性和侦听器
- 创建一个新类,该类延伸自
JButton
或AbstractButton
并提供核心功能/属性编在一个自包含包 - 你可以提供你自己的UI委托,和自定义按键的外观和感觉为核心
每一种方法都有它的优点和缺点,你需要决定哪些更好的满足你的整体需求。
例如,将自定义的外观和感觉代理提供到现有代码库非常容易,因为您不需要更改代码,除非要在使用它时安装外观和感觉
以下是使用外观和感觉委托的示例,这只是一个概念证明,可能还有很多额外的功能/工作需要完成 - 例如,我想提供更多提示有关要使用的颜色和翻转边框的厚度,例如
import java.awt.Color;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javaapplication24.Test.MetroLookAndFeel;
import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.plaf.basic.BasicButtonUI;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setBorder(new EmptyBorder(10, 10, 10, 10));
JButton fancyPB = new JButton("Restart Now");
fancyPB.setUI(new MetroLookAndFeel());
JButton normalPB = new JButton("Restart Now");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(4, 4, 4, 4);
add(fancyPB, gbc);
add(normalPB, gbc);
}
}
public class MetroLookAndFeel extends BasicButtonUI {
// This could be computed properties, where the border color
// is determined based on other properties
private Border focusBorder = new CompoundBorder(new LineBorder(Color.DARK_GRAY, 3), new EmptyBorder(7, 13, 7, 14));
private Border unfocusedBorder = new EmptyBorder(10, 14, 10, 14);
@Override
protected void installDefaults(AbstractButton b) {
super.installDefaults(b);
Font f = new Font("Segoe UI", Font.PLAIN, 20);
Color gray = new Color(204, 204, 204);
b.setFont(f);
b.setBackground(gray);
b.setContentAreaFilled(false);
b.setFocusPainted(false);
// This seems like an oddity...
b.setFocusable(false);
b.setForeground(Color.BLACK);
// b.setBorder(BorderFactory.createEmptyBorder(10, 14, 10, 14));
b.setBorder(unfocusedBorder);
}
@Override
protected void installListeners(AbstractButton b) {
super.installListeners(b);
b.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
((JButton)e.getSource()).setBorder(focusBorder);
}
@Override
public void mouseExited(MouseEvent e) {
((JButton)e.getSource()).setBorder(unfocusedBorder);
}
});
}
}
}