Swing:创建一个UWP(“Metro”) - 类似按钮 [英] Swing: Create a UWP ("Metro")–like button

查看:196
本文介绍了Swing:创建一个UWP(“Metro”) - 类似按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想设计一个看起来像UWP的Swing按钮 - 就像[Windows设置应用]一样:

I'd like to design a Swing button that would look like an UWP one – like so [Windows Settings App]:

这是我到目前为止:

使用以下代码:

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,都无法更改背景颜色(布尔b); 属性设置为 false true ,因为 EmptyBorder 继承Windows Swing按钮的默认颜色。

The background color cannot be changed at all, regardless whether button.setContentAreaFilled(Boolean b); property is set to false or true, since the EmptyBorder inherits the default color for Windows Swing buttons.

悬停(悬停时颜色变化)也停止使用属性集到 false

Hovering (color change on hover) also stops to function with the property set to false.

设置 button.setContentAreaFilled(true); 给出以下结果,这也是不理想的,因为按钮的背景仍然没有从默认颜色改变(+它有一个轮廓):

Setting button.setContentAreaFilled(true); gives the following result which is also not ideal, since the button's background still isn't changed from the default color (+it has an outline):

我的问题是,基本上:如何修改我的代码以获得以下类似UWP的设计?

My question is, basically: how to modify my code in order to get the following UWP–like design?

默认值:

悬停:

推荐答案

你可以通过多种方式做到这一点,你可以

There are a number of ways you "might" do this, you could


  • 创建工厂方法以应用模拟功能所需的属性和侦听器

  • 创建一个从 JButton 扩展的新类或 AbstractButton 并在自包含的软件包中提供所需的核心功能/属性

  • 您可以提供自己的UI委托,并自定义核心按钮的外观和感觉

  • Create a factory method to apply the properties and listeners you need to mimic the functionality
  • Create a new class which extends from JButton or AbstractButton and provide core functionality/properties you need in a self contained package
  • You could provide you own UI delegate, and customise the look and feel of the button at the core

每种方法都有它的优点和缺点,你需要决定哪种更符合你的整体需求。

Each method has it's pros and cons and you need to decide which better meets you overall needs.

例如,它是mu ch更容易为现有代码库提供自定义外观和代理,因为您不需要更改代码,而是在您想要使用它时安装外观

For example, it's much easier to supply a customised look and feel delegate into an existing code base, as you don't need to change the code, other then to install the look and feel when you want to use it

以下是使用外观代理的示例,这只是一个概念证明,可能还有许多其他功能/工作需要完成 - 例如,我想要提供有关要使用的颜色和边框上滚动厚度的更多提示,例如

The following is an example of using a look and feel delegate, this is just a proof of concept and there are probably a lot of additional functionality/work that needs to be done - for example, I'd like to supply more hints about the colors to use and the thickness of the roll over border, for example

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);
                }                
            });
        }

    }

}

这篇关于Swing:创建一个UWP(“Metro”) - 类似按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆