2012-01-19 39 views
3

我想实现一个按钮,看起来像这样button复杂的按键布局

Round button w/metallic border

但随着四个部分外环鸿沟,让我有四个图像,使的它加上按钮中间图像为中间按钮。对于四个按键的划分想象是有交叉或X.我该如何布局的按钮来实现这样的一个组成部分?

我试着用BorderLayoutGridBagLayout,但由于摆动按钮的长方形空间使每个按钮图像之间空间太大,所以它看起来并不好。现在我想的JLayeredPane叠加的按钮,但我认为会有,如果另一个按钮是在它的一个问题,按钮的某些部分将无法点击。

是否有可能实现这种形状与functionnalities(5个按钮)我想的组成部分?

+1

你能否找到你的换档键,并始终如一地用它来开始句子和单词'I'?我试着阅读那些乱七八糟的信件,但一直迷迷糊糊。另外*“.. surimposed按钮..”*要么仔细打字或得到一个拼写检查。 –

+0

顺便说一句 - 那形象是一个按钮,但你一直提到“按钮”(复数 - 很多)。 DYM单个按钮还是多个按钮? –

+0

顺便说一句,感谢真棒教程:)) – COD3BOY

回答

1

我意识到这个问题,有人问相当长一段时间以前,但我会创建呈现为按钮,然后检查被点击图像的哪一部分的JComponent。像这样:

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.Toolkit; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.geom.Ellipse2D; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.LinkedList; 
import java.util.List; 

import javax.swing.JComponent; 
import javax.swing.SwingConstants; 

public class FivePartCircleButton extends JComponent implements SwingConstants 
{ 
    private static final float PERCENT_PADDING_MIDDLE = 0.1571428571428571f; 
    private static final float PERCENT_PADDING_EDGE = 0.0535714285714286f; 
    private static Image button; 

    private List<ActionListener> topListeners = new LinkedList<ActionListener>(); 
    private List<ActionListener> rightListeners = new LinkedList<ActionListener>(); 
    private List<ActionListener> bottomListeners = new LinkedList<ActionListener>(); 
    private List<ActionListener> leftListeners = new LinkedList<ActionListener>(); 
    private List<ActionListener> middleListeners = new LinkedList<ActionListener>(); 
    private String actionCommand; 

    public FivePartCircleButton() 
    { 
     try 
     { 
      if (button == null) 
       button = Toolkit.getDefaultToolkit().createImage(new URL("http://mygimptutorial.com/preview/round-web20-button-with-metal-ring.jpg")); 
     } 
     catch (MalformedURLException e) {e.printStackTrace();} 

     this.setPreferredSize(new Dimension(280, 280)); 
     this.addMouseListener(mouseAdapter); 
    } 

    private MouseAdapter mouseAdapter = new MouseAdapter() 
    { 
     @Override 
     public void mouseClicked(MouseEvent e) 
     { 
      Ellipse2D innerCircle = getShapeOfOval(PERCENT_PADDING_MIDDLE); 
      Ellipse2D outerCircle = getShapeOfOval(PERCENT_PADDING_EDGE); 

      if (innerCircle.contains(e.getPoint())) //clicked in the inner circle 
       processClick(middleListeners); 
      else if (outerCircle.contains(e.getPoint())) //clicked in the outer ring 
      {    
       float lineFromTopLeftToBottomRight = e.getY() * ((float)getWidth()/(float)getHeight()); //if we split this button diagonally (top left to bottom right), then this is the x position of that line at this y point 
       float lineFromTopRightToBottomLeft = getWidth() - lineFromTopLeftToBottomRight; // the same line as tlBrDividerX but mirrored 

       if (e.getX() < lineFromTopLeftToBottomRight) //clicked on the bottom left half of the ring 
       { 
        if (e.getX() < lineFromTopRightToBottomLeft) //clicked on the left quadrant of the ring 
         processClick(leftListeners); 
        else //clicked on the bottom quadrant of the ring 
         processClick(bottomListeners); 
       } 
       else //clicked on the top right half of the ring 
       { 
        if (e.getX() < lineFromTopRightToBottomLeft) //clicked on the top quadrant of the ring 
         processClick(topListeners); 
        else //clicked on the right quadrant of the ring 
         processClick(rightListeners); 
       } 
      } 
     } 
    }; 

    /** 
    * Informs all of the listeners that an action has been performed 
    * @param listeners - which set of listeners to inform 
    */ 
    private void processClick(List<ActionListener> listeners) 
    { 
     for (ActionListener l : listeners) 
      l.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, actionCommand)); 
    } 

    /** 
    * @param listener - the listener to add 
    * @param side - one of SwingConstants.TOP, SwingConstants.RIGHT, SwingConstants.BOTTOM, SwingConstants.LEFT, SwingConstants.CENTER, 
    */ 
    public void addActionListener(ActionListener listener, int side) 
    { 
     switch (side) 
     { 
     case TOP: 
      topListeners.add(listener); 
      break; 
     case RIGHT: 
      rightListeners.add(listener); 
      break; 
     case BOTTOM: 
      bottomListeners.add(listener); 
      break; 
     case LEFT: 
      leftListeners.add(listener); 
      break; 
     case CENTER: 
      middleListeners.add(listener); 
      break; 
     } 
    } 

    /** 
    * Creates an oval based on the size of this component with the given padding percentage 
    * @param percentPadding 
    * @return an oval with the given padding 
    */ 
    private Ellipse2D getShapeOfOval(float percentPadding) 
    { 
     float x = getWidth() * percentPadding; 
     float y = getHeight() * percentPadding; 
     float w = getWidth() - x - x; 
     float h = getHeight() - y - y; 

     Ellipse2D circle = new Ellipse2D.Float(x, y, w, h); 
     return circle; 
    } 

    @Override 
    protected void paintComponent(Graphics g) 
    { 
     g.drawImage(button, 0, 0, this.getWidth(), this.getHeight(), this); 
    } 

    /** 
    * Sets the action command for this button. 
    * @param actionCommand - the action command for this button 
    */ 
    public void setActionCommand(String actionCommand) 
    { 
     this.actionCommand = actionCommand; 
    } 
} 

简而言之按钮油漆作为图像链接到您。然后,当你点击图像时,它会检查你点击的图像的哪一部分。这是通过创建两个与图像上的椭圆匹配的椭圆来完成的。如果您单击的点位于较小的椭圆内,则会通知中间的ActionListeners。如果不是内部的,但它是较大的椭圆形里面,那么我们就知道点击在擂台。然后我们检查看看椭圆的哪一侧被点击并通知适当的动作监听器。

此外,请注意:PERCENT_PADDING_MIDDLEPERCENT_PADDING_EDGE是特定于您链接到的图像,并假定图像周围有相同的填充。这取决于图像上填充像素的数量并将其除以图像的宽度。