继续我的评论...
这是我做的一个例子,希望对您有所帮助:
基本上覆盖componentResized(ComponentEvent e)
将JFrame
其形状更改为RoundRectangle2D
. 然后 aJPanel
添加自定义 AbstarctBorder
以处理边框的圆形边缘。
import java.awt.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.geom.RoundRectangle2D;
import javax.swing.*;
import javax.swing.border.AbstractBorder;
public class ShapedWindowAndBorderDemo extends JFrame {
public ShapedWindowAndBorderDemo() {
super("Shaped Window and Border Demo");
final JPanel panel = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
};
// It is best practice to set the window's shape in
// the componentResized method. Then, if the window
// changes size, the shape will be correctly recalculated.
addComponentListener(new ComponentAdapter() {
// Give the window an elliptical shape.
// If the window is resized, the shape is recalculated here.
@Override
public void componentResized(ComponentEvent e) {
setShape(new RoundRectangle2D.Float(panel.getX(), panel.getY(), panel.getWidth(), panel.getHeight(), 10, 10));
}
});
setUndecorated(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//panel.setBorder(new CurvedBorder());//creates a single lined border
panel.setBorder(new CurvedBorder(2, true));
panel.add(new JButton("I am a Button"));
add(panel);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
// Determine what the GraphicsDevice can support.
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
//If shaped windows aren't supported, exit.
if (!gd.isWindowTranslucencySupported(PERPIXEL_TRANSPARENT)) {
System.err.println("Shaped windows are not supported");
System.exit(0);
}
// Create the GUI on the event-dispatching thread
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ShapedWindowAndBorderDemo();
}
});
}
}
class CurvedBorder extends AbstractBorder {
private Color wallColor = Color.gray;
private int sinkLevel = 1;
private boolean indent = false;
public CurvedBorder(Color wall) {
this.wallColor = wall;
}
public CurvedBorder(int sinkLevel, Color wall, boolean indent) {
this.wallColor = wall;
this.sinkLevel = sinkLevel;
}
public CurvedBorder(int sinkLevel, boolean indent) {
this.sinkLevel = sinkLevel;
this.indent = indent;
}
public CurvedBorder() {
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
super.paintBorder(c, g, x, y, w, h);
g.setColor(getWallColor());
for (int i = 0; i < sinkLevel; i++) {
g.drawRoundRect(x, y, w - 1 - i, h - 1 - i, 10 - i, 10 - i);
if (indent) {
g.drawRoundRect(x + i, y + i, w - 1, h - 1, 10 - i, 10 - i);
}
}
}
@Override
public boolean isBorderOpaque() {
return true;
}
@Override
public Insets getBorderInsets(Component c) {
return new Insets(sinkLevel, sinkLevel, sinkLevel, sinkLevel);
}
@Override
public Insets getBorderInsets(Component c, Insets i) {
i.left = i.right = i.bottom = i.top = sinkLevel;
return i;
}
public boolean isIndented() {
return indent;
}
public int getSinkLevel() {
return sinkLevel;
}
public Color getWallColor() {
return wallColor;
}
}
参考