父对象具有背景图像时的圆角边框
Rounded borders when parent object has a background image
我正在尝试制作圆角边框。边界内应该是设置了边界的组件决定绘制的任何东西,边界外应该是"nothing";也就是说,它应该在那些地方绘制父组件的油漆。
我想得到什么:
我得到的是:
查看带有蓝色边框的容器的白色角。我需要摆脱他们。我正在尝试通过自定义 Border
来实现此目的:
public class RoundedLineBorder extends AbstractBorder {
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2 = (Graphics2D) g;
int arc = 20;
RoundRectangle2D borderRect = new RoundRectangle2D.Double(
0, 0, width - 1, height - 1, arc, arc);
Rectangle fullRect = new Rectangle(
0, 0, width, height);
Area borderArea = new Area(borderRect);
Area parentArea = new Area(fullRect);
parentArea.subtract(borderArea);
Component parent = c.getParent();
if (parent != null) {
g2.setColor(parent.getBackground());
/* fill parent background color outside borders */
g2.setClip(parentArea);
g2.fillRect(fullRect);
g2.setClip(null);
}
g2.setColor(Color.blue);
/* draw borders */
g2.draw(borderArea);
}
}
这在父组件有纯色背景时工作正常,但如果它有背景图片
它当然没有。有没有办法获得在下面绘制的实际颜色
上述地点?
是否有更好的方法在不实际扩展 JPanel
的情况下实现圆角边框
并在 paintComponent
?
中完成所有操作
it requires a tight coupling between the border and the component,
您可以创建一个容器组件来执行此操作,这样您就不需要自定义每个组件。
类似于:
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.*;
public class RoundedBorderContainer extends JPanel implements Border
{
private boolean componentWasOpaque;
public RoundedBorderContainer(JComponent component)
{
setLayout( new BorderLayout() );
add( component );
componentWasOpaque = component.isOpaque();
component.setOpaque( false );
setOpaque( false );
setBorder( this );
}
@Override
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
int arc = 20;
int width = getWidth();
int height = getHeight();
RoundRectangle2D borderRect = new RoundRectangle2D.Double(0, 0, width, height, arc, arc);
g2.setClip(borderRect);
super.paint(g);
super.paintBorder(g);
g2.setClip( null );
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if (componentWasOpaque)
{
g.setColor(getComponent(0).getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
}
}
@Override
public Insets getBorderInsets(Component c)
{
return new Insets(1, 1, 1, 1);
}
@Override
public boolean isBorderOpaque()
{
return false;
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height)
{
Graphics2D g2 = (Graphics2D) g;
int arc = 20;
RoundRectangle2D borderRect = new RoundRectangle2D.Double(0, 0, width - 1, height - 1, arc, arc);
Rectangle fullRect = new Rectangle(0, 0, width, height);
Area borderArea = new Area(borderRect);
borderArea = new Area(borderRect);
Area parentArea = new Area(fullRect);
g2.setColor(Color.RED);
g2.draw(borderArea);
}
private static void createAndShowGUI()
{
JLabel label = new JLabel( new ImageIcon("grass.jpg") );
label.setLayout( new GridBagLayout() );
JPanel panel = new JPanel();
panel.setPreferredSize( new Dimension(100, 100) );
panel.setBackground( Color.BLACK );
// JLabel panel = new JLabel( new ImageIcon("???") );
RoundedBorderContainer rbc = new RoundedBorderContainer(panel);
label.add(rbc);
JFrame frame = new JFrame("Rounded Border");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( label );
frame.setLocationByPlatform( true );
// frame.pack();
frame.setSize(400, 400);
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
我正在尝试制作圆角边框。边界内应该是设置了边界的组件决定绘制的任何东西,边界外应该是"nothing";也就是说,它应该在那些地方绘制父组件的油漆。
我想得到什么:
我得到的是:
查看带有蓝色边框的容器的白色角。我需要摆脱他们。我正在尝试通过自定义 Border
来实现此目的:
public class RoundedLineBorder extends AbstractBorder {
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2 = (Graphics2D) g;
int arc = 20;
RoundRectangle2D borderRect = new RoundRectangle2D.Double(
0, 0, width - 1, height - 1, arc, arc);
Rectangle fullRect = new Rectangle(
0, 0, width, height);
Area borderArea = new Area(borderRect);
Area parentArea = new Area(fullRect);
parentArea.subtract(borderArea);
Component parent = c.getParent();
if (parent != null) {
g2.setColor(parent.getBackground());
/* fill parent background color outside borders */
g2.setClip(parentArea);
g2.fillRect(fullRect);
g2.setClip(null);
}
g2.setColor(Color.blue);
/* draw borders */
g2.draw(borderArea);
}
}
这在父组件有纯色背景时工作正常,但如果它有背景图片 它当然没有。有没有办法获得在下面绘制的实际颜色 上述地点?
是否有更好的方法在不实际扩展 JPanel
的情况下实现圆角边框
并在 paintComponent
?
it requires a tight coupling between the border and the component,
您可以创建一个容器组件来执行此操作,这样您就不需要自定义每个组件。
类似于:
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.*;
public class RoundedBorderContainer extends JPanel implements Border
{
private boolean componentWasOpaque;
public RoundedBorderContainer(JComponent component)
{
setLayout( new BorderLayout() );
add( component );
componentWasOpaque = component.isOpaque();
component.setOpaque( false );
setOpaque( false );
setBorder( this );
}
@Override
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
int arc = 20;
int width = getWidth();
int height = getHeight();
RoundRectangle2D borderRect = new RoundRectangle2D.Double(0, 0, width, height, arc, arc);
g2.setClip(borderRect);
super.paint(g);
super.paintBorder(g);
g2.setClip( null );
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if (componentWasOpaque)
{
g.setColor(getComponent(0).getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
}
}
@Override
public Insets getBorderInsets(Component c)
{
return new Insets(1, 1, 1, 1);
}
@Override
public boolean isBorderOpaque()
{
return false;
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height)
{
Graphics2D g2 = (Graphics2D) g;
int arc = 20;
RoundRectangle2D borderRect = new RoundRectangle2D.Double(0, 0, width - 1, height - 1, arc, arc);
Rectangle fullRect = new Rectangle(0, 0, width, height);
Area borderArea = new Area(borderRect);
borderArea = new Area(borderRect);
Area parentArea = new Area(fullRect);
g2.setColor(Color.RED);
g2.draw(borderArea);
}
private static void createAndShowGUI()
{
JLabel label = new JLabel( new ImageIcon("grass.jpg") );
label.setLayout( new GridBagLayout() );
JPanel panel = new JPanel();
panel.setPreferredSize( new Dimension(100, 100) );
panel.setBackground( Color.BLACK );
// JLabel panel = new JLabel( new ImageIcon("???") );
RoundedBorderContainer rbc = new RoundedBorderContainer(panel);
label.add(rbc);
JFrame frame = new JFrame("Rounded Border");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( label );
frame.setLocationByPlatform( true );
// frame.pack();
frame.setSize(400, 400);
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}