例如,您可以使用Area...
public class TestPane extends JPanel {
public TestPane() {
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Area area = new Area(new Rectangle(10, 10, getWidth() - 20, getHeight() - 20));
area.subtract(new Area(new Rectangle(20, getHeight() / 2, getWidth() / 2, getHeight() - 10)));
g2d.draw(area);
g2d.dispose();
}
}
您定义一个自定义形状...
public class TestPane extends JPanel {
public TestPane() {
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Path2D path = new Path2D.Float();
path.moveTo(10, 10);
path.lineTo(getWidth() - 20, 10);
path.lineTo(getWidth() - 20, getHeight() - 20);
path.lineTo(getWidth() / 2, getHeight() - 20);
path.lineTo(getWidth() / 2, getHeight() / 2);
path.lineTo(20, getHeight() / 2);
path.lineTo(20, getHeight() - 20);
path.lineTo(10, getHeight() - 20);
path.closePath();
g2d.draw(path);
g2d.dispose();
}
}
实际上编写自定义边框会非常非常困难,因为形状样式不规则,组件实际包含在哪里?
可能会创建两个或多个边框,然后可以对其进行布局,以便显示为一个
更多详情请见Working with Geometry
更新为Border 示例...
让Border 实际工作要困难得多,因为预期边框的内部区域将是矩形。
根据您提供的复杂形状,一种解决方案是实际创建两个边框,一个左右钻孔,负责为要在其中布局的组件生成一个“安全”区域,例如:
public class LeftBorder implements Border {
private int offset;
public LeftBorder(int offset) {
this.offset = offset;
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Path2D path = new Path2D.Float();
int xOffset = x + offset;
int yOffset = y + offset;
width -= offset;
height -= offset * 2;
float gap = width * 0.1f;
path.moveTo(xOffset, yOffset);
path.lineTo(xOffset + width, yOffset);
path.moveTo(xOffset, yOffset);
path.lineTo(xOffset, yOffset + height);
path.lineTo(xOffset + gap, yOffset + height);
path.lineTo(xOffset + gap, yOffset + (height - (height / 2)));
path.lineTo(xOffset + width, yOffset + (height - (height / 2)));
((Graphics2D)g).draw(path);
}
@Override
public Insets getBorderInsets(Component c) {
int height = c.getHeight();
height -= (height / 2);
System.out.println(height);
return new Insets(offset + 4, offset + 4, height + 4, 0);
}
@Override
public boolean isBorderOpaque() {
return false;
}
}
public class RightBorder implements Border {
private int offset;
public RightBorder(int offset) {
this.offset = offset;
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Path2D path = new Path2D.Float();
int xOffset = x;
int yOffset = y + offset;
width -= offset;
height -= offset * 2;
path.moveTo(xOffset, yOffset);
path.lineTo(xOffset + width, yOffset);
path.lineTo(xOffset + width, yOffset + height);
path.lineTo(xOffset, yOffset + height);
path.lineTo(xOffset, yOffset + (height - (height / 2)));
((Graphics2D)g).draw(path);
}
@Override
public Insets getBorderInsets(Component c) {
return new Insets(offset + 4, 0, offset + 4, offset + 4);
}
@Override
public boolean isBorderOpaque() {
return false;
}
}
这将要求您提供至少两个相同高度的面板,例如:
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
public class Main {
public static void main(String args[]) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(new LeftPane());
frame.add(new RightPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class RightPane extends JPanel {
public RightPane() {
setBorder(new RightBorder(10));
setLayout(new GridBagLayout());
add(new JLabel("Righty"));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class LeftPane extends JPanel {
public LeftPane() {
setBorder(new LeftBorder(10));
setLayout(new GridBagLayout());
add(new JLabel("Lefty"));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
这也将依赖于布局管理器能够将两个组件彼此相邻布局