如何设计带圆角的 JButton?
How do I design a JButton with round corners?
我正在尝试设计一个 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);
}
}
我尝试用圆弧绘制,但是当我在 paintComponent 中使用 ((Graphics2D)g).draw(arc)
时。鼠标在GUI上一直报错
我该如何处理?
我创建了以下 GUI。
我没有扩展 JButton
,而是创建了一个 class 来容纳两个 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;
}
}
}
我正在尝试设计一个 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);
}
}
我尝试用圆弧绘制,但是当我在 paintComponent 中使用 ((Graphics2D)g).draw(arc)
时。鼠标在GUI上一直报错
我该如何处理?
我创建了以下 GUI。
我没有扩展 JButton
,而是创建了一个 class 来容纳两个 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;
}
}
}