简体   繁体   English

如何使用Swing运行后台任务?

[英]How can I run background tasks with Swing?

Im currently making some sort of "Paint" with Swing components. 我目前正在使用Swing组件进行某种“绘制”。 It can only draw ellipses, rectangles and lines. 它只能绘制椭圆,矩形和线条。 The problem is, everytime I switch figures, the other figures won't remain on the JPanel. 问题是,每次切换数字时,其他数字都不会保留在JPanel上。 Every figure of the same type remains, for example: If I start drawing lines, they remain in the JPanel until I change of figure. 保留相同类型的每个图形,例如:如果我开始绘制线条,它们将保留在JPanel中,直到我更改图形为止。 Every figure I'm drawing gets saved to a class where I have defined the attributes of: 我绘制的每个图形都保存到定义了以下属性的类中:

  • StartPoint 起点
  • LastPoint 最后一点
  • TypeOfFigure 图类型
  • OutLineColor OutLineColor
  • FillingColor 填充颜​​色

And every object of that class is saved to an ArrayList. 并且该类的每个对象都保存到ArrayList中。 How can I redraw the elements of that arraylist everytime I switch figures? 每次切换图形时,如何重新绘制该数组列表的元素? Heres my draw() method 这是我的draw()方法

private void draw() {
        mMouseIsDragging = false;
        mMouseReleased = false;
        MyPanel.this.addMouseListener(new MouseAdapter() {
            private Coordenadas mDraw;
            @Override
            public void mousePressed(MouseEvent e) {
                mCoordenadas.add(new Coordenadas());
                mDraw = (Coordenadas) MyPanel.this.mCoordenadas.get(MyPanel.this.mCoordenadas.size() - 1);
                mDraw.setColor(mColorLinea);
                mDraw.setColorRelleno(mColorRelleno);
                mDraw.setTipo(mOpcion);
                mStartPoint = e.getPoint();
                mDraw.setFirstPoint(e.getPoint());
                mMouseIsDragging = true;
           }
            @Override
            public void mouseReleased(MouseEvent e) {
                mDraw = (Coordenadas) MyPanel.this.mCoordenadas.get(MyPanel.this.mCoordenadas.size() - 1);
                mPuntoFinal = e.getPoint();
                mDraw.setLastPoint(e.getPoint());
                mMouseReleased = true;
                mMouseIsDragging = false;
                repaint();
            }
        });
        MyPanel.this.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                mPuntoFinal = e.getPoint();
                mMouseReleased = false;
                mMouseIsDragging = true;
                repaint();
            }
        });
    }

And this is the paintComponent method parts making the draw of these figures: 这是paintComponent方法的组成部分,这些图的绘制:

if (mMouseReleased == true && mMouseIsDragging == false) {
            for (int i = 0; i < mCoordenadas.size(); i++) {
                Coordenadas mCoord = (Coordenadas) mCoordenadas.get(i);
                switch (mCoord.getTipo()) {
                    case 1:
                        mG2D.setColor(mCoord.getColor());
                        mG2D.drawLine(mCoord.getFirstPoint().x, mCoord.getFirstPoint().y, mCoord.getLastPoint().x, mCoord.getLastPoint().y);
                        break;
                    case 2:
                        if (mCoord.getColorRelleno() != null) {
                            mG2D.setPaint(mCoord.getColorRelleno());
                            mG2D.fill(new Rectangle2D.Double(mCoord.getFirstPoint().x, mCoord.getFirstPoint().y, Math.abs(mCoord.getFirstPoint().x - mCoord.getLastPoint().x), Math.abs(mCoord.getFirstPoint().y - mCoord.getLastPoint().y)));
                        } else {
                            mG2D.setColor(mCoord.getColor());
                            mG2D.drawRect(mCoord.getFirstPoint().x, mCoord.getFirstPoint().y, Math.abs(mCoord.getFirstPoint().x - mCoord.getLastPoint().x), Math.abs(mCoord.getFirstPoint().y - mCoord.getLastPoint().y));
                        }
                        break;
                    case 3:
                        if (mCoord.getColorRelleno() != null) {
                            mG2D.setPaint(mCoord.getColorRelleno());
                            mG2D.fill(new Ellipse2D.Double(mCoord.getFirstPoint().y, mCoord.getFirstPoint().x, mCoord.getLastPoint().x, mCoord.getLastPoint().y));
                        } else {
                            mG2D.setColor(mCoord.getColor());
                            mG2D.drawOval(mCoord.getFirstPoint().x, mCoord.getFirstPoint().y, mCoord.getLastPoint().x, mCoord.getLastPoint().y);
                        }
                        break;
                }
            }
        }
if (mMouseReleased == false && mMouseIsDragging == true) {
            if (mColorRelleno != null) {
                mG2D.setBackground(mColorRelleno);
            } else {
                mG2D.setColor(mColorLinea);
            }
            switch (mOpcion) {
                case 1:
                    mG2D.drawLine(mPuntoInicio.x, mPuntoInicio.y, mPuntoFinal.x, mPuntoFinal.y);
                    break;
                case 2:
                    mG2D.drawRect(mPuntoInicio.x, mPuntoInicio.y, Math.abs(mPuntoInicio.x - mPuntoFinal.x), Math.abs(mPuntoInicio.y - mPuntoFinal.y));
                    break;
                case 3:
                    mG2D.drawOval(mPuntoInicio.x, mPuntoInicio.y, mPuntoFinal.x, mPuntoFinal.y);
                    break;
            }
        }

Sorry for mixing english and spanish here, I just made this D: The first if enters when the mouse is released and not dragging obviously, but somehow when I switch figures, it doesn't paint the figures that are inside the arraylist, which in this case is mCoordenadas. 抱歉,我在这里混合了英语和西班牙语,我做了这个D:第一个if是在释放鼠标并且没有明显拖动时输入的,但是以某种方式切换图形时,它不会绘制arraylist内的图形,这个案子是mCoordenadas。 How can I run this in another thread? 如何在另一个线程中运行它? Or better expressed, do I need a thread to handle this? 或者更好的表达,我需要一个线程来处理吗?

Imagine a painter working on a canvas. 想象一下画家在画布上工作。 From time to time he grabs a bucket with paint, and pours that over his canvas. 他不时抓起一个油漆桶,将其倒在画布上。 Everything that was there before ... "vanishes". 之前存在的一切……“消失了”。

That is what you do when calling 那就是你打电话时要做的

mG2D.fill(new Rectangle2D.Double(mCoord.getFirstPoint().x, ...                         

within your paintComponent() method. 在paintComponent()方法中。

Thing is: you have a certain (complicated) condition there; 事实是:您那里有某种(复杂)状况; and what happens is basically: whenever the correct conditions come together, you flood-fill your canvas; 基本上发生了什么:只要有正确的条件,您就会在画布上泛滥; thereby "overwriting" any prior content. 从而“覆盖”任何先前的内容。

Beyond that: this is probably a good example of the DRY principle: you have the same code in various places; 除此之外:这可能是DRY原理的一个很好的例子:您在不同的地方都有相同的代码; and lost track of that. 并对此一无所知。

Instead: make sure that anything your code should do is written up in exactly one place. 相反:确保任何你的代码应该做的是在只有一个地方写出来。

In other words: you shouldn't have multiple calls to fill. 换句话说:您不应有多个呼叫来填补。 Instead: step back, and identify "blocks of common behavior" - and extract them into a method. 取而代之的是:退后一步,找出“常见行为的障碍”-并将其提取到方法中。

Or better expressed, do I need a thread to handle this? 或者更好的表达,我需要一个线程来处理吗?

Threads has nothing to do with this. 线程与此无关。

mCoordenadas.add(new Coordenadas());

Don't add a new panel. 不要添加新面板。 All painting must be done on the same panel. 所有绘画必须在同一面板上完成。

The ArrayList must contain a generic "shape" object. ArrayList必须包含一个通用的“ shape”对象。 So the ArrayList can contain ellipse, rectangle and line shapes. 因此,ArrayList可以包含椭圆,矩形和线形。 Each "shape" must know how to paint itself. 每个“形状”都必须知道如何绘画。

What might change when you switch figures is the MouseListener logic. 切换图形时可能发生的变化是MouseListener逻辑。 You might remove the old listener and add the new listener for the newly selected shape. 您可以删除旧的侦听器,然后为新选择的形状添加新的侦听器。

it doesn't paint the figures that are inside the arraylist, 它不会绘制arraylist内的数字,

Another option is to paint directly to a BufferedImage , then you don't have to worry about repainting objects. 另一个选择是直接绘制到BufferedImage ,则不必担心重新绘制对象。

Check out Custom Painting Approaches for working examples of both approaches: 1) painting from an ArrayList and 2) painting to a BufferedImage. 请查看“ 自定义绘画方法”以获取这两种方法的工作示例:1)从ArrayList绘画,以及2)绘画到BufferedImage。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM