2017-09-27 12 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); 
       }     
      }); 
     } 

    } 

}