2012-12-13 397 views
0

我想要一個圓邊的按鈕。我的按鈕有一個黃色的背景顏色。我無法獲得我的按鈕的圓形邊緣。這裏是我想要的代碼帶圓邊的按鈕

class RoundedBorder implements Border { 
     int radius; 
     RoundedBorder(int radius) { 
      this.radius = radius; 
     } 
     public Insets getBorderInsets(Component c) { 
      return new Insets(this.radius+1, this.radius+1, this.radius+2, this.radius); 
     } 
     public boolean isBorderOpaque() { 
      return true; 
     } 
     public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { 
      g.drawRoundRect(x,y,width-1,height-1,radius,radius); 
     } 
    } 

jButton1.setText(aContinue); 
     jButton1.setBackground(new java.awt.Color(255, 255, 0)); 
     jButton1.setBorder(new RoundedBorder(20)); 

我不能使用這段代碼繞過邊緣。下面是我的按鈕的外觀。

enter image description here

我想有沒有四溢的背景色輪邊緣。

+5

不要讓史蒂夫·喬布斯看到了這個問題....他發明四捨五入邊緣! – Neal

回答

4

找到這個偉大的例子由甲骨文提供了一個類,創建RoundButton

enter image description here

下面是使用編輯RoundButton類來創建RoundedButton類的例子:

enter image description here

import java.awt.AWTEvent; 
import java.awt.AWTEventMulticaster; 
import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.FontMetrics; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JTextField; 
import javax.swing.SwingUtilities; 


public class Test { 

    public Test() { 
     initComponents(); 
    } 

    private void initComponents() { 
     final JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     final JTextField tf = new JTextField(""); 

     RoundedButton rb = new RoundedButton("Go"); 
     rb.setBackground(Color.yellow); 
     rb.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent ae) { 
       JOptionPane.showMessageDialog(frame, "You said: " + tf.getText()); 
      } 
     }); 

     frame.add(tf, BorderLayout.NORTH); 
     frame.add(rb); 

     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Test(); 
      } 
     }); 
    } 
} 

class RoundedButton extends Component { 

    ActionListener actionListener;  // Post action events to listeners 
    String label;      // The Button's text 
    protected boolean pressed = false; // true if the button is detented. 

    /** 
    * Constructs a RoundedButton with no label. 
    */ 
    public RoundedButton() { 
     this(""); 
    } 

    /** 
    * Constructs a RoundedButton with the specified label. 
    * 
    * @param label the label of the button 
    */ 
    public RoundedButton(String label) { 
     this.label = label; 
     enableEvents(AWTEvent.MOUSE_EVENT_MASK); 
    } 

    /** 
    * gets the label 
    * 
    * @see setLabel 
    */ 
    public String getLabel() { 
     return label; 
    } 

    /** 
    * sets the label 
    * 
    * @see getLabel 
    */ 
    public void setLabel(String label) { 
     this.label = label; 
     invalidate(); 
     repaint(); 
    } 

    /** 
    * paints the RoundedButton 
    */ 
    @Override 
    public void paint(Graphics g) { 

     // paint the interior of the button 
     if (pressed) { 
      g.setColor(getBackground().darker().darker()); 
     } else { 
      g.setColor(getBackground()); 
     } 
     g.fillRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 20, 20); 

     // draw the perimeter of the button 
     g.setColor(getBackground().darker().darker().darker()); 
     g.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 20, 20); 

     // draw the label centered in the button 
     Font f = getFont(); 
     if (f != null) { 
      FontMetrics fm = getFontMetrics(getFont()); 
      g.setColor(getForeground()); 
      g.drawString(label, getWidth()/2 - fm.stringWidth(label)/2, getHeight()/2 + fm.getMaxDescent()); 
     } 
    } 

    /** 
    * The preferred size of the button. 
    */ 
    @Override 
    public Dimension getPreferredSize() { 
     Font f = getFont(); 
     if (f != null) { 
      FontMetrics fm = getFontMetrics(getFont()); 
      int max = Math.max(fm.stringWidth(label) + 40, fm.getHeight() + 40); 
      return new Dimension(max, max); 
     } else { 
      return new Dimension(100, 100); 
     } 
    } 

    /** 
    * The minimum size of the button. 
    */ 
    @Override 
    public Dimension getMinimumSize() { 
     return new Dimension(100, 100); 
    } 

    /** 
    * Adds the specified action listener to receive action events from this 
    * button. 
    * 
    * @param listener the action listener 
    */ 
    public void addActionListener(ActionListener listener) { 
     actionListener = AWTEventMulticaster.add(actionListener, listener); 
     enableEvents(AWTEvent.MOUSE_EVENT_MASK); 
    } 

    /** 
    * Removes the specified action listener so it no longer receives action 
    * events from this button. 
    * 
    * @param listener the action listener 
    */ 
    public void removeActionListener(ActionListener listener) { 
     actionListener = AWTEventMulticaster.remove(actionListener, listener); 
    } 

    /** 
    * Determine if click was inside round button. 
    */ 
    @Override 
    public boolean contains(int x, int y) { 
     int mx = getSize().width/2; 
     int my = getSize().height/2; 
     return (((mx - x) * (mx - x) + (my - y) * (my - y)) <= mx * mx); 
    } 

    /** 
    * Paints the button and distribute an action event to all listeners. 
    */ 
    @Override 
    public void processMouseEvent(MouseEvent e) { 
     Graphics g; 
     switch (e.getID()) { 
      case MouseEvent.MOUSE_PRESSED: 
       // render myself inverted.... 
       pressed = true; 

       // Repaint might flicker a bit. To avoid this, you can use 
       // double buffering (see the Gauge example). 
       repaint(); 
       break; 
      case MouseEvent.MOUSE_RELEASED: 
       if (actionListener != null) { 
        actionListener.actionPerformed(new ActionEvent(
          this, ActionEvent.ACTION_PERFORMED, label)); 
       } 
       // render myself normal again 
       if (pressed == true) { 
        pressed = false; 

        // Repaint might flicker a bit. To avoid this, you can use 
        // double buffering (see the Gauge example). 
        repaint(); 
       } 
       break; 
      case MouseEvent.MOUSE_ENTERED: 

       break; 
      case MouseEvent.MOUSE_EXITED: 
       if (pressed == true) { 
        // Cancel! Don't send action event. 
        pressed = false; 

        // Repaint might flicker a bit. To avoid this, you can use 
        // double buffering (see the Gauge example). 
        repaint(); 

        // Note: for a more complete button implementation, 
        // you wouldn't want to cancel at this point, but 
        // rather detect when the mouse re-entered, and 
        // re-highlight the button. There are a few state 
        // issues that that you need to handle, which we leave 
        // this an an excercise for the reader (I always 
        // wanted to say that!) 
       } 
       break; 
     } 
     super.processMouseEvent(e); 
    } 
} 
+0

真棒幫助..謝謝..這個代碼可以調整爲jtextfield? – Rags

+1

@Ragssure它可以但實際上它會成爲一個全新的類,Exortns組件類而不是調整原始的,因爲JTextField與JButton非常不同 –

+0

我不知道該怎麼做......如果你花點時間。 .pls試圖幫助我... – Rags

0

實現此目的的另一個乾淨方法是定義一個定製的ButtonUI,該定製將繪製一個圓角按鈕。

+0

如何定義一個ButtonUI ..你可以分享一個示例代碼 – Rags

1

在我看來,

public boolean isBorderOpaque() { 
     return false; 
    } 

    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { 
     // Stroke width? 
     g.drawRoundRect(x,y,width-1,height-1,radius,radius); 
    } 
5

選項1 - 使用圖片

1選項 - 使用下面的代碼(從Make a button round中提取)

import java.awt.*; 
import java.awt.geom.*; 
import javax.swing.*; 

public class RoundButton extends JButton { 
    public RoundButton(String label) { 
    super(label); 

// These statements enlarge the button so that it 
// becomes a circle rather than an oval. 
    Dimension size = getPreferredSize(); 
    size.width = size.height = Math.max(size.width, 
     size.height); 
    setPreferredSize(size); 

// This call causes the JButton not to paint 
    // the background. 
// This allows us to paint a round background. 
    setContentAreaFilled(false); 
    } 

// Paint the round background and label. 
    protected void paintComponent(Graphics g) { 
    if (getModel().isArmed()) { 
// You might want to make the highlight color 
    // a property of the RoundButton class. 
     g.setColor(Color.lightGray); 
    } else { 
     g.setColor(getBackground()); 
    } 
    g.fillOval(0, 0, getSize().width-1, 
     getSize().height-1); 

// This call will paint the label and the 
    // focus rectangle. 
    super.paintComponent(g); 
    } 

// Paint the border of the button using a simple stroke. 
    protected void paintBorder(Graphics g) { 
    g.setColor(getForeground()); 
    g.drawOval(0, 0, getSize().width-1, 
     getSize().height-1); 
    } 

// Hit detection. 
    Shape shape; 
    public boolean contains(int x, int y) { 
// If the button has changed size, 
    // make a new shape object. 
    if (shape == null || 
     !shape.getBounds().equals(getBounds())) { 
     shape = new Ellipse2D.Float(0, 0, 
     getWidth(), getHeight()); 
    } 
    return shape.contains(x, y); 
    } 

// Test routine. 
    public static void main(String[] args) { 
// Create a button with the label "Jackpot". 
    JButton button = new RoundButton("Jackpot"); 
    button.setBackground(Color.green); 

// Create a frame in which to show the button. 
    JFrame frame = new JFrame(); 
    frame.getContentPane().setBackground(Color.yellow); 
    frame.getContentPane().add(button); 
    frame.getContentPane().setLayout(new FlowLayout()); 
    frame.setSize(150, 150); 
    frame.setVisible(true); 
    } 
} 

2選項 - 用look感覺支持Rou nd按鈕http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/NimbusLookandFeel_OBE2012/CustomizingLandF.html

選項4 - 使用JavaFX並使用CSS。有免費的CSS腳本支持這個