我是摇摆中的新手,并且有一个问题,如何更好地绘制这个形状:
我以两种方式思考
请提供建议,我们将非常感谢您的示例!
答案 0 :(得分:1)
您可以使用多边形类(java.awt.Polygon
)
int xs = new int[]{1,2,3...7}; //your x-coordinates
int ys = new int[]{1,2,3...7}; //your y-coordinates
Shape irr = new Polygon(xs, ys, xs.length);
如果您想使用某些边框,可以使用Graphics2D
public void paintComponent(Graphics gr){
Graphics2D g2d = (Graphics2D)gr;
GradientPaint redToWhite = new GradientPaint(0,0,color.RED,100, 0,color.WHITE);
g2d.setPaint(redtowhite)
g2d.fill(irr); //fill special color
Stroke customBorder = getCustomBorder();
g2d.setStroke(customBorder);
g2d.draw(irr); //draw 'special' borders
}
请注意,Polygon
实施了contains(double x, double y)
方法,可让您检测自己是否在内部
答案 1 :(得分:1)
您可以使用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);
}
}
}
这也将使布局管理器能够将两个组件布置在彼此旁边
答案 2 :(得分:1)
看看Java 2D API。它可以帮助您绘制复杂的形状。
E.g。
class IrregularShape extends JComponent {
private int strokeWidth;
IrregularShape(int strokeWidth){
this.strokeWidth = strokeWidth;
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D newGraphics = (Graphics2D) g.create();
Insets borderInsets = new Insets(0, 0, 0, 0);
Border border = getBorder();
if (border != null) {
borderInsets = border.getBorderInsets(this);
}
BasicStroke basicStroke = new BasicStroke(strokeWidth);
newGraphics.setStroke(basicStroke);
int x = getX() + borderInsets.left + strokeWidth;
int y = getY() + borderInsets.top + strokeWidth;
int width = getWidth() - x - borderInsets.right - strokeWidth;
int height = getHeight() - y - borderInsets.bottom - strokeWidth;
Double outterRactangleDouble = new Rectangle2D.Double(x, y, width, height);
Area outterRectangle = new Area(outterRactangleDouble);
Area innerRectangle = new Area(outterRactangleDouble);
AffineTransform affineTransform = new AffineTransform();
affineTransform.scale(0.5, 0.5);
affineTransform.translate(x + width * 0.10, y + height * 1.2);
innerRectangle.transform(affineTransform);
outterRectangle.subtract(innerRectangle);
newGraphics.draw(outterRectangle);
}
}
public class MainFrame {
public static void main(String[] args) {
JFrame frame = new JFrame("Irregular Shape");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Container contentPane = frame.getContentPane();
contentPane.add(new IrregularShape(3));
frame.setSize(640, 150);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
并且它也可以调整大小
答案 3 :(得分:0)
除了我的第一个回答https://stackoverflow.com/a/34287251/974186
您也可以将其实现为边框。
class IrregularBorder implements Border {
private int thickness;
public IrregularBorder(int thickness) {
this.thickness = thickness;
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width,
int height) {
Graphics2D graphics2d = (Graphics2D) g;
BasicStroke basicStroke = new BasicStroke(thickness);
graphics2d.setStroke(basicStroke);
int halfThickness = thickness / 2;
Double outterRactangleDouble = new Rectangle2D.Double(
x + halfThickness, y + halfThickness, width - thickness,
height - thickness);
Area outterRectangle = new Area(outterRactangleDouble);
Area innerRectangle = computeInnerRect(x, y, width, height,
outterRactangleDouble);
outterRectangle.subtract(innerRectangle);
graphics2d.draw(outterRectangle);
}
private Area computeInnerRect(int x, int y, int width, int height,
Double outterRactangleDouble) {
Area innerRectangle = new Area(outterRactangleDouble);
AffineTransform affineTransform = new AffineTransform();
affineTransform.scale(0.5, 0.5);
affineTransform.translate(x + width * 0.10, y + height * 1.2);
innerRectangle.transform(affineTransform);
return innerRectangle;
}
@Override
public Insets getBorderInsets(Component c) {
int left = (int) (thickness + (c.getWidth() * 0.6));
return new Insets(thickness, left, thickness, thickness);
}
@Override
public boolean isBorderOpaque() {
return true;
}
}
并照常使用
public class MainFrame {
public static void main(String[] args) {
JFrame frame = new JFrame("Irregular Shape");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Container contentPane = frame.getContentPane();
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
contentPane.add(mainPanel);
JPanel irregularShapeBorderedPanel = new JPanel(new BorderLayout());
irregularShapeBorderedPanel.add(new JButton("Button"),
BorderLayout.CENTER);
irregularShapeBorderedPanel.setBorder(new IrregularBorder(2));
mainPanel.add(irregularShapeBorderedPanel);
frame.setSize(640, 150);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}