Java 复杂按钮布局
我想实现一个如下所示的按钮: 但是外圈被分成四部分,我有四个图像来制作它的按钮,加上中间按钮的中间图像。对于四个按钮的划分,假设有一个十字或一个X。如何布局按钮以实现这样的组件 我试过使用Java 复杂按钮布局,java,swing,jbutton,Java,Swing,Jbutton,我想实现一个如下所示的按钮: 但是外圈被分成四部分,我有四个图像来制作它的按钮,加上中间按钮的中间图像。对于四个按钮的划分,假设有一个十字或一个X。如何布局按钮以实现这样的组件 我试过使用BorderLayout和gridbagloayout,但是由于摆动按钮的矩形形状而产生的空间在每个按钮图像之间造成了太多的空间,所以看起来不太好。我现在想用JLayeredPane来叠加按钮,但我认为会有一个问题,因为如果另一个按钮在上面,按钮的某些部分将无法单击 是否可以使用我想要的功能性(5个按钮)实现
BorderLayout
和gridbagloayout
,但是由于摆动按钮的矩形形状而产生的空间在每个按钮图像之间造成了太多的空间,所以看起来不太好。我现在想用JLayeredPane
来叠加按钮,但我认为会有一个问题,因为如果另一个按钮在上面,按钮的某些部分将无法单击
是否可以使用我想要的功能性(5个按钮)实现此形状的组件?我意识到这个问题很久以前就被问到了,但我会创建一个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;
}
}
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Image;
导入java.awt.Toolkit;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.awt.geom.Ellipse2D;
导入java.net.MalformedURLException;
导入java.net.URL;
导入java.util.LinkedList;
导入java.util.List;
导入javax.swing.JComponent;
导入javax.swing.SwingConstants;
公共类FivePartCircleButton扩展JComponent实现SwingConstants
{
私有静态最终浮动百分比_PADDING _MIDDLE=0.1571421428571428571f;
专用静态最终浮动百分比_PADDING _EDGE=0.0535714285714286f;
私有静态图像按钮;
private List topListeners=new LinkedList();
private List rightListeners=新建LinkedList();
private List bottomListeners=new LinkedList();
private List leftListeners=new LinkedList();
私有列表middleListeners=newLinkedList();
私有字符串操作命令;
公共五部分圆形按钮()
{
尝试
{
如果(按钮==null)
button=Toolkit.getDefaultToolkit().createImage(新URL(“http://mygimptutorial.com/preview/round-web20-button-with-metal-ring.jpg"));
}
catch(畸形异常){e.printStackTrace();}
此.setPreferredSize(新维度(280280));
这是addMouseListener(mouseAdapter);
}
private MouseAdapter MouseAdapter=new MouseAdapter()
{
@凌驾
公共无效mouseClicked(MouseEvent e)
{
Ellipse2D内圆=GetShapeFoval(百分之_PADDING_MIDDLE);
Ellipse2D outerCircle=GetShapeOffVal(填充边缘的百分比);
if(innerCircle.contains(e.getPoint())//在内圈中单击
processClick(中间侦听器);
else if(outerCircle.contains(e.getPoint())//在外环中单击
{
float lineFromTopLeftToBottomRight=e.getY()*((float)getWidth()/(float)getHeight());//如果按对角线(从左上到右下)拆分此按钮,则这是该线在该y点的x位置
float lineFromTopRightToBottomLeft=getWidth()-lineFromTopLeftToBottomRight;//与tlBrDividerX相同,但镜像
如果(e.getX()