问题描述
我正在尝试设计一个 JButton。
我希望 JButton 看起来像这样:
我尝试使用 polygon
来实现此目的,但无法使角变圆,如上所示。
我设计的看起来像这样:
public class arcButton extends JButton{
public arcButton() {
Dimension size = getPreferredSize();
size.width = size.height = Math.max(size.width,size.height);
setPreferredSize(size);
setContentAreaFilled(false);
}
protected void paintComponent(Graphics g) {
if (getModel().isArmed()) {
g.setColor(Color.CYAN.darker().darker());
} else {
g.setColor(Color.CYAN.darker());
}
int xPoints[] = {getWidth(),getWidth()/3,getWidth()*3/4,getWidth(),getWidth()};
int yPoints[] = {getHeight()*7/9,getHeight()*7/9,getHeight()*3/9,getHeight()*4/9,getHeight()*2/9,getHeight()/9,getHeight(),getHeight()};
g.fillpolygon(xPoints,yPoints,xPoints.length);
super.paintComponent(g);
}
protected void paintBorder(Graphics g) {
g.setColor(Color.cyan);
int xPoints[] = {getWidth(),getHeight()};
g.drawpolygon(xPoints,xPoints.length);
}
polygon polygon;
public boolean contains(int x,int y) {
if (polygon == null ||
!polygon.getBounds().equals(getBounds())) {
int xPoints[] = {getWidth(),getWidth()};
int yPoints[] = {getHeight()*7/9,getHeight()};
polygon = new polygon(xPoints,xPoints.length);
}
return polygon.contains(x,y);
}
}
我尝试用弧线绘制,但是当我在paintComponent 中使用((Graphics2D)g).draw(arc)
时。当鼠标在 GUI 上时,它不断给出很多错误。
我应该如何处理这个问题?
解决方法
我创建了以下 GUI。
我没有扩展 JButton
,而是创建了一个类来保存两个 BufferedImages
。一个表示箭头,一个表示按下的按钮。
我创建了一个测试 GUI,因此我可以一次绘制一小块箭头。我最终创建了两个 Polygons
,一个用于半圆,一个用于箭头。
这是完整的可运行代码。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class CustonButtonGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new CustonButtonGUI());
}
private ButtonImages buttonImages;
public CustonButtonGUI() {
this.buttonImages = new ButtonImages();
}
@Override
public void run() {
JFrame frame = new JFrame("Custom JButton");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(),BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new FlowLayout());
panel.setBorder(BorderFactory.createEmptyBorder(100,100,100));
BufferedImage image = buttonImages.getMainImage();
JButton button = new JButton();
button.setPreferredSize(new Dimension(image.getWidth(panel),image.getHeight(panel)));
button.setIcon(new ImageIcon(image));
button.setPressedIcon(new ImageIcon(buttonImages.getPressedImage()));
panel.add(button);
return panel;
}
private class ButtonImages {
private final BufferedImage mainImage;
private final BufferedImage pressedImage;
public ButtonImages() {
this.mainImage = createMainImage(120,200);
this.pressedImage = createPressedImage(120,200);
}
private BufferedImage createMainImage(int width,int height) {
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D) image.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.WHITE);
g2d.fillRect(0,width,height);
g2d.setColor(Color.BLACK);
g2d.fillPolygon(createArrowPolygon(width,height));
g2d.fillPolygon(createCircularPolygon(width,height));
g2d.dispose();
return image;
}
private Polygon createArrowPolygon(int width,int height) {
Polygon polygon = new Polygon();
int margin = 10;
int arrowWidth = 30;
int x = width - margin;
int y = height - margin;
polygon.addPoint(x,y - arrowWidth);
polygon.addPoint(x - arrowWidth,y - arrowWidth - arrowWidth);
polygon.addPoint(x - arrowWidth,y);
return polygon;
}
private Polygon createCircularPolygon(int width,int height) {
Polygon polygon = new Polygon();
int centerY = height / 2;
int margin = 10;
Point centerPoint = new Point(width - margin - 30,centerY);
double radius = centerY - 55.0;
for (int angle = 90; angle <= 270; angle++) {
double theta = Math.toRadians(angle);
int x = (int) Math.round(Math.cos(theta) * radius) + centerPoint.x;
int y = (int) Math.round(Math.sin(theta) * radius) + centerPoint.y;
polygon.addPoint(x,y);
}
radius += 25.0;
for (int angle = 270; angle >= 90; angle--) {
double theta = Math.toRadians(angle);
int x = (int) Math.round(Math.cos(theta) * radius) + centerPoint.x;
int y = (int) Math.round(Math.sin(theta) * radius) + centerPoint.y;
polygon.addPoint(x,y);
}
return polygon;
}
private BufferedImage createPressedImage(int width,BufferedImage.TYPE_INT_RGB);
return image;
}
public BufferedImage getMainImage() {
return mainImage;
}
public BufferedImage getPressedImage() {
return pressedImage;
}
}
}