对于我的java应用程序,我需要一个圆形矩形,其轮廓看起来像一个普通的矩形,就像这个
我知道你可以通过在其中绘制一个普通的矩形和一个RoundRect来做到这一点,但我不想在其中绘制一个RoundRect,因为我想在其中绘制其他内容。
这是一个圆角的正常角落。我如何用Java绘制它?
问题是如果我使用图层,矩形看起来像这样: 角落充满了错误的颜色。我该如何预防?
答案 0 :(得分:10)
我可以想到两种方法。第一个是生成Shape
,表示方形外边缘和圆形内边缘。
第二种方法是使用AlphaComposite
生成屏蔽结果。
public class TestMask {
public static void main(String[] args) {
new TestMask();
}
public TestMask() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new MaskedPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MaskedPane extends JPanel {
public MaskedPane() {
setBackground(Color.RED);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
BufferedImage outter = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = outter.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose();
BufferedImage inner = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
g2d = inner.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.BLACK);
g2d.fillRoundRect(10, 10, getWidth() - 20, getHeight() - 20, 20, 20);
g2d.dispose();
BufferedImage masked = applyMask(outter, inner, AlphaComposite.DST_OUT);
g.drawImage(masked, 0, 0, this);
}
public BufferedImage applyMask(BufferedImage sourceImage, BufferedImage maskImage, int method) {
BufferedImage maskedImage = null;
if (sourceImage != null) {
int width = maskImage.getWidth();
int height = maskImage.getHeight();
maskedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D mg = maskedImage.createGraphics();
int x = (width - sourceImage.getWidth()) / 2;
int y = (height - sourceImage.getHeight()) / 2;
mg.drawImage(sourceImage, x, y, null);
mg.setComposite(AlphaComposite.getInstance(method));
mg.drawImage(maskImage, 0, 0, null);
mg.dispose();
}
return maskedImage;
}
public BufferedImage applyMask(BufferedImage sourceImage, BufferedImage maskImage) {
return (BufferedImage) applyMask(sourceImage, maskImage, AlphaComposite.DST_IN);
}
}
}
已更新为Shape示例
终于有时间敲出一个......
public class TestMask {
public static void main(String[] args) {
new TestMask();
}
public TestMask() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ShapedPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ShapedPane extends JPanel {
public ShapedPane() {
setBackground(Color.GREEN);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.BLACK);
g2d.fill(new RounedFrame(getWidth(), getHeight(), 10, 20));
g2d.dispose();
}
}
public class RounedFrame extends Path2D.Float {
public RounedFrame(float width, float height, float thickness, float radius) {
moveTo(0, 0);
lineTo(width, 0);
lineTo(width, height);
lineTo(0, height);
lineTo(0, 0);
float innerWidth = width - thickness;
float innerHeight = height - thickness;
moveTo(thickness + radius, thickness);
lineTo(innerWidth - radius, thickness);
curveTo(innerWidth, thickness, innerWidth, thickness, innerWidth, thickness + radius);
lineTo(innerWidth, innerHeight - radius);
curveTo(innerWidth, innerHeight, innerWidth, innerHeight, innerWidth - radius, innerHeight);
lineTo(thickness + radius, innerHeight);
curveTo(thickness, innerHeight, thickness, innerHeight, thickness, innerHeight - radius);
lineTo(thickness, thickness + radius);
curveTo(thickness, thickness, thickness, thickness, thickness + radius, thickness);
closePath();
setWindingRule(WIND_EVEN_ODD);
}
}
}
<强>更新强>
根据Andrew的评论,您可以使用Area
你可以用上面的例子替换上面例子中的paintComponent
......
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Area area = new Area(new Rectangle(0, 0, getWidth(), getHeight()));
area.subtract(new Area(new RoundRectangle2D.Float(10, 10, getWidth() - 20, getHeight() - 20, 20, 20)));
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.BLACK);
g2d.fill(area);
g2d.dispose();
}
哪个更简单:D
答案 1 :(得分:8)
类似的东西:
paintComponent(Graphics g) {
//If you want more: Graphics2D g2 = (Graphics2D) g;
Rect rect = getBounds();
g.setColor(Color.BLACK);
g.fillRect(rect.x, rect,y, rect.width, rect.height);
rect.grow(-4, -4);
g.setColor(getBackground());
g.fillRoundRect(rect.x, rect,y, rect.width, rect.height, 5, 5);
}
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
class CustomBorderWithContent {
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
int w = 200;
int h = 100;
int pad = 4;
BufferedImage img = new BufferedImage(
w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = img.createGraphics();
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// Ripped/adapted from Joop's answer
g.setColor(Color.BLACK);
g.fillRect(0, 0, w, h);
g.setColor(Color.ORANGE);
g.fillRoundRect(pad, pad, w-2*pad, h-2*pad, 25, 25);
// Now..
g.setColor(Color.BLUE);
g.drawString("Something else..", 20, 25);
g.dispose();
JOptionPane.showMessageDialog(
null, new JLabel(new ImageIcon(img)));
}
};
SwingUtilities.invokeLater(r);
}
}