gpt4 book ai didi

java - PaintComponent 的一些问题

转载 作者:行者123 更新时间:2023-12-02 02:25:04 25 4
gpt4 key购买 nike

我在使用 PaintComponent 绘制形状时遇到不清楚的问题。

public class Shape extends JPanel {
private String shape;
private boolean isFill;
private int x;
private int y;
private int width;
private int height;
private Color color;

public Shape(String shape, boolean isFill, int x, int y, int width, int height, Color color) {
this.shape = shape;
this.isFill = isFill;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
}
@Override
public boolean equals (Object O){
if (O instanceof Shape){
if (this.getWidth() == ((Shape) O).getWidth() && this.getHeight() == ((Shape) O).getHeight()){
return true;
}
}
return false;
}

@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(this.getColor());
if (this.getShape().equals(Constants.IS_RECTANGLE)){
if (this.isFill()){
g.fillRect(this.getX(), this.getY(),this.getWidth(),this.getHeight());
}
else{
g.drawRect(this.getX(), this.getY(),this.getWidth(),this.getHeight());
}
}
else{
if (this.isFill()){
g.fillOval(this.getX(), this.getY(),this.getWidth(),this.getHeight());
}
else{
g.drawOval(this.getX(), this.getY(),this.getWidth(),this.getHeight());
}
}
}

public void drawShape(JPanel panel){
panel.add(this);
panel.setVisible(true);
}

这是我的 Shape 类,我想将一些添加到面板中(使用 JPanel)。

public class GuiManagement {

public JFrame createScreen(){
// Creating the screen
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle(Constants.APP_NAME);
frame.setSize(Constants.SCREEN_WIDTH,Constants.SCREEN_HEIGHT);
return frame;
}

public JPanel createPanel(JFrame frame, int x, int y, int width, int height, String borderSpace){
// Creates a panel, set its bounds and direction in the screen
JPanel panel = new JPanel();
panel.setLayout(null);
panel.setBounds(x,y,width,height);
frame.add(panel, borderSpace);
panel.setVisible(true);
return panel;
}

这些是我创建并返回框架和面板的两个函数。

public static void main (String [] args){
GuiManagement g = new GuiManagement();
JFrame frame = g.createScreen();
JPanel panel = g.createPanel(frame,0,0,800,800,BorderLayout.NORTH);
panel.setBackground(Color.GREEN);
Shape s = new Shape("Oval",true,40,40,100,100,Color.DARK_GRAY);
s.drawShape(panel);

frame.setLayout(new BorderLayout(30,30));
frame.setVisible(true);
}

这就是主类。现在,程序应该绘制一个简单的椭圆形,但是当我运行主函数时,看起来面板分配了正确的空间来绘制形状(框架的绿色部分是我创建的面板),但绘制了它仅在该空间的一小部分。我在下图中添加了问题的示例。 PRINT SCREEN EXAMPLE OF THE PROBLEM HERE!!!

感谢您的帮助! :)

最佳答案

因此,您遇到了一系列复杂的问题,并且对 Swing 中坐标系统的工作原理存在根本性误解。

正在做...

g.fillRect(this.getX(), this.getY(),this.getWidth(),this.getHeight());

这是一个坏主意。

getXgetY 表示组件在其父组件空间内的位置,因此您现在已将绘图位置偏移了 x * 2y * 2

I renamed the getX and getY functions

好吧,这不在你的原始代码中,它只会导致更多困惑

所以,我使用...设置了一个小测试

Shape shape = new Shape("", true, 25, 25, 50, 50, Color.RED);
shape.setBorder(new LineBorder(Color.BLUE));
shape.setBounds(25, 25, 50, 50);

(我修改了形状以始终绘制椭圆形),这会产生...

Bad offset

您可以看到形状现在在 Shape 组件内发生偏移。

相反,您应该从 0x0 开始绘制,这将是 Shape 组件的左上角/左上角。

我修改了 Shape 代码以使用...

if (this.isFill()) {
g.fillOval(0, 0, this.getWidth(), this.getHeight());
} else {
g.drawOval(0, 0, this.getWidth(), this.getHeight());
}

现在它生成...

Better positioned

恕我直言,以这种方式使用组件是一个坏主意。 null 布局是出了名的难以管理,如果您只想绘制形状,那么纯自定义绘制路线通常更好/更容易管理。

这个想法基本上构建了一个可以绘制任意数量的“形状”对象的单个组件

因为我喜欢从一个可以构建的“抽象”概念开始,所以我从 Shape 的基本概念开始,它定义了所有 Shape< 的所有信息 实现需要...

public interface Shape {
public Rectangle getBounds();
public boolean isFilled();
public Color getColor();
public void paint(Graphics2D g2d);
}

然后我定义一个抽象实现,它涵盖了核心/通用功能......

public abstract class AbstractShape implements Shape {
private Rectangle bounds;
private boolean filled;
private Color color;

public AbstractShape(Rectangle bounds, boolean filled, Color color) {
this.bounds = bounds;
this.filled = filled;
this.color = color;
}

public Rectangle getBounds() {
return bounds;
}

public boolean isFilled() {
return filled;
}

public Color getColor() {
return color;
}

}

然后我定义实际的实现,在本例中,我只完成了 OvalShape,但您可以有三角形、矩形、弧形和上方形状...

public class OvalShape extends AbstractShape {

public OvalShape(Rectangle bounds, boolean filled, Color color) {
super(bounds, filled, color);
}

@Override
public void paint(Graphics2D g2d) {
g2d.setColor(this.getColor());
Rectangle bounds = getBounds();
if (isFilled()) {
g2d.fillOval(bounds.x, bounds.y, bounds.width, bounds.height);
} else {
g2d.drawOval(bounds.x, bounds.y, bounds.width, bounds.height);
}
}

}

然后,我们需要某种方法来显示这些形状......

public class ShapeContainer extends JPanel {
private List<Shape> shapes;

public ShapeContainer() {
shapes = new ArrayList<>(25);
}

public void add(Shape shape) {
shapes.add(shape);
repaint();
}

@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Shape shape : shapes) {
Graphics2D g2d = (Graphics2D) g.create();
shape.paint(g2d);
g2d.dispose();
}
}



}

这意味着,所有形状都在容器坐标上下文中工作,如果您想在轨道上添加新功能,则无需担心尝试翻译它们...

因为我知道这可能有点需要接受,一个可运行的例子......

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test {

public static void main(String[] args) {
new Test();
}

public Test() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
Shape shape = new OvalShape(new Rectangle(25, 24, 50, 50), true, Color.RED);

ShapeContainer container = new ShapeContainer();
container.add(shape);

frame.add(container);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public interface Shape {
public Rectangle getBounds();
public boolean isFilled();
public Color getColor();
public void paint(Graphics2D g2d);
}

public abstract class AbstractShape implements Shape {
private Rectangle bounds;
private boolean filled;
private Color color;

public AbstractShape(Rectangle bounds, boolean filled, Color color) {
this.bounds = bounds;
this.filled = filled;
this.color = color;
}

public Rectangle getBounds() {
return bounds;
}

public boolean isFilled() {
return filled;
}

public Color getColor() {
return color;
}

}

public class OvalShape extends AbstractShape {

public OvalShape(Rectangle bounds, boolean filled, Color color) {
super(bounds, filled, color);
}

@Override
public void paint(Graphics2D g2d) {
g2d.setColor(this.getColor());
Rectangle bounds = getBounds();
if (isFilled()) {
g2d.fillOval(bounds.x, bounds.y, bounds.width, bounds.height);
} else {
g2d.drawOval(bounds.x, bounds.y, bounds.width, bounds.height);
}
}

}

public class ShapeContainer extends JPanel {
private List<Shape> shapes;

public ShapeContainer() {
shapes = new ArrayList<>(25);
}

public void add(Shape shape) {
shapes.add(shape);
repaint();
}

@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Shape shape : shapes) {
Graphics2D g2d = (Graphics2D) g.create();
shape.paint(g2d);
g2d.dispose();
}
}



}
}

关于java - PaintComponent 的一些问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47914227/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com