Вы можете использовать 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);
}
}
}
Это также будет полезным для менеджера компоновки, который мог бы компоновать два компонента рядом друг с другом.
Что вы имеете в виду под "границы"? – MadProgrammer
См. Также [Граница с закругленными углами и прозрачностью] (http://stackoverflow.com/questions/15025092/border-with-rounded-corners-transparency). –
благодарим за ответы! – altavista23