【问题标题】:Can I use getComponents() instead of keeping an ArrayList of components?我可以使用 getComponents() 而不是保留组件的 ArrayList 吗?
【发布时间】:2021-08-16 09:18:48
【问题描述】:

我有一个应用程序,用户可以通过单击位置 (x,y) 来动态添加形状,比如圆形(为简单起见)。我一直在保留一个圆的 ArrayList,因此它们通过 paintComponent() 方法重新添加到 JPanel,但是我怀疑这可能是多余的,因为保留了一个幕后数组,可以通过内置 getComponents() 方法。我对吗?我的代码的关键部分如下:

public class DrawingPanel extends JPanel implements Constants {
Point point;
Figure figure;

public DrawingPanel() {
    point = new Point(0, 0);
    figure = new Circle(point, defaultSize);
    setLayout(null);
    setBackground(Color.white);
    setPreferredSize(new Dimension(450, 450));
    addMouseListener(new ActionHandler());
}

public void paintComponent(Graphics page) {
    super.paintComponent(page);
    add(figure);
    }

private class ActionHandler extends MouseAdapter {

    @Override
    public void mousePressed(MouseEvent e) {
        super.mousePressed(e);
        Point point = e.getPoint();
        System.out.println("Mouse pressed at (" + e.getX() + ", " + e.getY() + ")");

        String figureState = itemHandler.getFigureState();
        String figureActionState = itemHandler.getFigureActionState();

        if (figureActionState.equals("None")) {
            switch (figureState) {
                case "Circle" -> {
                    figure = new Circle(point, defaultSize);
                    figure.setBounds((int) point.getX(), (int) point.getY(), 50, 50);
                    figure.addMouseListener(new ActionHandler());
                }
                case "Square" -> {
                    figure = new Rect(point, defaultSize);
                    figure.setBounds((int) point.getX(), (int) point.getY(), 50, 50);
                    figure.addMouseListener(new ActionHandler());
                }
                case "Cross" -> {
                    figure = new Cross(point, defaultSize);
                    figure.setBounds((int) point.getX(), (int) point.getY(), 50, 50);
                    figure.addMouseListener(new ActionHandler());
                }
            }
        }
        repaint();
    }
}

}

public class Figure extends JComponent {
Point position;
Dimension size;

public Figure(Point position, Dimension size) {
    this.position = position;
    this.size = size;
}

public void paintComponent(Graphics page) {
    super.paintComponent(page);
}

}

public interface Constants {
ItemHandler itemHandler = new ItemHandler();
Dimension defaultSize = new Dimension(50, 50);

}

【问题讨论】:

  • 容器 getComponents 方法返回一个 Swing 组件数组,如 JLabel、JButton 等。您保留一个 Figure 实例列表,其中 Figure 应该是普通 Java getter / setter 的实例班级。由于您没有发布代码,因此我不知道 Figure 是什么。
  • “我的代码的关键部分如下:” 为了尽快获得更好的帮助,edit 添加minimal reproducible exampleShort, Self Contained, Correct Example顺便说一句: 虽然使用getComponents 可能是可能的,但这不是一个好的编程习惯。保留对感兴趣组件的(单独)引用。
  • 感谢您的反馈。我已经更新了代码以包含图形类。此外,我没有意识到但怀疑我不需要重新跟踪添加到面板中的所有对象;那个paintComponent 负责这个。我重新添加了调整后的代码,似乎正在做我现在想要做的事情。
  • 但怀疑,我不需要重新跟踪添加到面板的所有对象;该paintComponent 会处理这个 不。所有paintComponent() 方法所做的只是绘制单个组件。 JLabel 的逻辑与 JButton 的逻辑不同。阅读 A Closer Look at the Painting Mechanism 上的 Swing 教程中的部分
  • @PaulRichardLewis,您更新的逻辑仍然错误。你没看我的回答吗?您不应该在paintComponent() 方法中向面板添加组件。创建组件时将组件添加到面板。事实上,如果您只是简单地尝试向面板添加组件,则无需重写 JPanel 的 paintComponent() 方法。

标签: java swing dynamic jpanel jcomponent


【解决方案1】:

您有整体设计问题:

  1. 绘画方法不应该改变类的状态。绘制方法应该只绘制类的当前状态。因此,您不应该在paintComponent() 方法中向面板添加组件。

  2. 我看不出保留这两个 ArrayList 的理由。组件应该知道如何绘制自身并包含绘制自身所需的所有信息。

也许你可以画一个Shape,而不是使用一个实际的组件。查看Drag a Painted Shape。它保留了所有要绘制的Shapes 的 ArrayList。此 ArrayList 用于标识您要拖动的Shape。您需要用现有的鼠标处理逻辑替换拖动逻辑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 2020-03-25
    • 2023-03-22
    • 2015-05-27
    • 2019-02-17
    • 1970-01-01
    • 2017-06-26
    相关资源
    最近更新 更多