java - 如何设计带圆角的 JButton?
问题描述
我正在尝试设计一个 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, getWidth()*3/4, getWidth()*3/4, getWidth(), getWidth()*3/4, getWidth()*3/4, 0, 0, getWidth()};
int yPoints[] = {getHeight()*7/9, getHeight()*7/9, getHeight()*3/9, getHeight()*3/9, getHeight()*4/9, getHeight()*2/9, 0, getHeight()/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(), getWidth()/3, getWidth()/3, getWidth()*3/4, getWidth()*3/4, getWidth(), getWidth()*3/4, getWidth()*3/4, 0, 0, getWidth()};
int yPoints[] = {getHeight()*7/9, getHeight()*7/9, getHeight()*3/9, getHeight()*3/9, getHeight()*4/9, getHeight()*2/9, 0, getHeight()/9, getHeight()/9, getHeight(), getHeight()};
g.drawPolygon(xPoints, yPoints, xPoints.length);
}
Polygon polygon;
public boolean contains(int x, int y) {
if (polygon == null ||
!polygon.getBounds().equals(getBounds())) {
int xPoints[] = {getWidth(), getWidth()/3, getWidth()/3, getWidth()*3/4, getWidth()*3/4, getWidth(), getWidth()*3/4, getWidth()*3/4, 0, 0, getWidth()};
int yPoints[] = {getHeight()*7/9, getHeight()*7/9, getHeight()*3/9, getHeight()*3/9, getHeight()*4/9, getHeight()*2/9, 0, getHeight()/9, getHeight()/9, getHeight(), getHeight()};
polygon = new Polygon(xPoints,yPoints,xPoints.length);
}
return polygon.contains(x, y);
}
}
我试图用弧线绘制,但是当我((Graphics2D)g).draw(arc)
在paintComponent中使用时。当鼠标在 GUI 上时,它不断给出很多错误。
我应该如何处理这个?
解决方案
我创建了以下 GUI。
我没有扩展 a 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, 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, 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, int height) {
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
return image;
}
public BufferedImage getMainImage() {
return mainImage;
}
public BufferedImage getPressedImage() {
return pressedImage;
}
}
}
推荐阅读
- python - 如何将 SeleniumLibrary 调整为无头模式
- java - 托管在 Heroku 上的 Spring Boot 项目 - Web 进程在启动后 90 秒内无法绑定到 $PORT
- swift - 如何使 UICollectionView 单元格可触摸/可点击?
- java - 如何在活动中打开 BottomNavigationView 菜单项
- bash - 用于删除断字字符的 Sed 脚本
- sql - 提高 Hive 中 Ntile 函数的速度
- node.js - Discord.js 反应收集器不听收集器.on('collect')
- javascript - 将 JSON XMLHttpRequest 的分页部分呈现为 HTML
- java - Heroku 未部署
- c - 编译后删除的可执行文件