2017-09-27 14 views
0

我想设计一个Swing的按钮,看起来像一个UWP一个 - 像这样的[Windows设置应用程序]: UWP button example摇摆:创建UWP(“新城”) - 就像按钮

这是什么我至今:

setContentAreaFilled(false)

使用下面的代码:

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);属性设置为falsetrue,因为EmptyBorder继承了Windows Swing按钮的默认颜色。

悬停(悬停时的颜色变化)也会停止以将属性设置为false

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

setContentAreaFilled(true)

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

默认:

default

悬停:

hovered

回答

1

下面是一个例子

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

为了操纵鼠标事件,如悬停,你”你必须对待这些事件如果要做的一个方法是创建你自己的按钮。


编辑

添加鼠标监听到你的按钮,由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

2

有许多的方法,你“可能”做到这一点,你可以

  • 创建一个工厂方法来申请您需要模拟功能的属性和侦听器
  • 创建一个新类,该类延伸自JButtonAbstractButton并提供核心功能/属性编在一个自包含包
  • 你可以提供你自己的UI委托,和自定义按键的外观和感觉为核心

每一种方法都有它的优点和缺点,你需要决定哪些更好的满足你的整体需求。

例如,将自定义的外观和感觉代理提供到现有代码库非常容易,因为您不需要更改代码,除非要在使用它时安装外观和感觉

以下是使用外观和感觉委托的示例,这只是一个概念证明,可能还有很多额外的功能/工作需要完成 - 例如,我想提供更多提示有关要使用的颜色和翻转边框的厚度,例如

NormalRollOver

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

    } 

}