简体   繁体   English

如何在两个不同的 JFrame 中绘制

[英]How to draw in two different JFrames

My goal is to implement a space filling curve in one frame, and in the other the number of each pixel in the frame.我的目标是在一帧中实现空间填充曲线,在另一帧中实现每个像素的数量。 In the future, I will need to draw some coordinates in the third frame.将来,我需要在第三帧中绘制一些坐标。 My question now is how do I draw the curve in one frame and the pixels in the other.我现在的问题是如何在一帧中绘制曲线而在另一帧中绘制像素。 I only get them in the same frame.我只把它们放在同一个框架中。

Here is the code:这是代码:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class HilbertCurve extends JPanel {

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            HilbertCurve exemplo1 = new HilbertCurve();
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(exemplo1);
            frame.pack();
            frame.setLocation(100,100);
            frame.setVisible(true);

            JFrame frame1 = new JFrame();
            frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame1.add(exemplo1);
            frame1.pack();
            frame1.setLocation(800, 100);
            frame1.setVisible(true);
        }
    });
}
private SimpleGraphics sg = null;
private int dist0 = 512;
private int dist = dist0;

public HilbertCurve() {
    sg = new SimpleGraphics();
}

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

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    int level = 4;
    dist = dist0;
    for (int i = level; i > 0; i--) {
        dist /= 2;
    }
    sg.goToXY(dist / 2, dist / 2);
    Graphics2D g2d = (Graphics2D) g.create();
    hilbertU(g2d, level);
    g2d.dispose();

}


private void hilbertU(Graphics2D g, int level) {
    if (level > 0) {
        hilbertD(g, level - 1);
        sg.lineRel(g, 0, dist);
        hilbertU(g, level - 1);
        sg.lineRel(g, dist, 0);
        hilbertU(g, level - 1);
        sg.lineRel(g, 0, -dist);
        hilbertC(g, level - 1);
    }
}

private void hilbertD(Graphics2D g, int level) {
    if (level > 0) {
        hilbertU(g, level - 1);
        sg.lineRel(g, dist, 0);
        hilbertD(g, level - 1);
        sg.lineRel(g, 0, dist);
        hilbertD(g, level - 1);
        sg.lineRel(g, -dist, 0);
        hilbertA(g, level - 1);
    }
}

private void hilbertC(Graphics2D g, int level) {
    if (level > 0) {
        hilbertA(g, level - 1);
        sg.lineRel(g, -dist, 0);
        hilbertC(g, level - 1);
        sg.lineRel(g, 0, -dist);
        hilbertC(g, level - 1);
        sg.lineRel(g, dist, 0);
        hilbertU(g, level - 1);
    }
}

private void hilbertA(Graphics2D g, int level) {
    if (level > 0) {
        hilbertC(g, level - 1);
        sg.lineRel(g, 0, -dist);
        hilbertA(g, level - 1);
        sg.lineRel(g, -dist, 0);
        hilbertA(g, level - 1);
        sg.lineRel(g, 0, dist);
        hilbertD(g, level - 1);
    }
}

} }

And the SimpleGraphics.java class和 SimpleGraphics.java 类

import java.awt.Graphics2D;

class SimpleGraphics {
    int a = 1;

    private int x = 0, y = 0;

    public SimpleGraphics() {
    }

    public void goToXY(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void lineRel(Graphics2D g, int deltaX, int deltaY) {
        g.drawLine(x, y, x + deltaX, y + deltaY);
        g.drawString(Integer.toString(a++), x+deltaX, y+deltaY);
        x += deltaX;
        y += deltaY;
    }
}

The output is: Output输出为:输出

The out put I want is: enter image description here我想要的输出是:在此处输入图像描述

Basically speaking, you want to decouple the data from the view.基本上来说,您希望将数据与视图分离。 The way in which the data "might" be rendered should be irrelevant to the data.数据“可能”呈现的方式应该与数据无关。

This concept is commonly know as "Model-View-Controller".这个概念通常被称为“模型-视图-控制器”。

To start with, you want to create a model of your "Hilbert Curve", which would be a bunch of points, each point representing the next point in the curve, for example...首先,您想创建一个“希尔伯特曲线”模型,这将是一堆点,每个点代表曲线中的下一个点,例如......

public class HilbertCurveModel {

    private List<Point> points;
    private int distribution;

    private int xDelta, yDelta;

    public HilbertCurveModel(int level, int size) {
        points = new ArrayList<>(25);
        distribution = size;
        for (int i = level; i > 0; i--) {
            distribution /= 2;
        }
        hilbertU(level);
    }

    public int getDistribution() {
        return distribution;
    }

    public List<Point> getPoints() {
        List<Point> copy = new ArrayList<>(points.size());
        for (Point p : points) {
            copy.add(new Point(p));
        }
        return copy;
    }

    protected void addLine(int x, int y) {
        points.add(new Point(x + xDelta, y + yDelta));
        xDelta += x;
        yDelta += y;
    }

    private void hilbertU(int level) {
        if (level > 0) {
            hilbertD(level - 1);
            addLine(0, distribution);
            hilbertU(level - 1);
            addLine(distribution, 0);
            hilbertU(level - 1);
            addLine(0, -distribution);
            hilbertC(level - 1);
        }
    }

    private void hilbertD(int level) {
        if (level > 0) {
            hilbertU(level - 1);
            addLine(distribution, 0);
            hilbertD(level - 1);
            addLine(0, distribution);
            hilbertD(level - 1);
            addLine(-distribution, 0);
            hilbertA(level - 1);
        }
    }

    private void hilbertC(int level) {
        if (level > 0) {
            hilbertA(level - 1);
            addLine(-distribution, 0);
            hilbertC(level - 1);
            addLine(0, -distribution);
            hilbertC(level - 1);
            addLine(distribution, 0);
            hilbertU(level - 1);
        }
    }

    private void hilbertA(int level) {
        if (level > 0) {
            hilbertC(level - 1);
            addLine(0, -distribution);
            hilbertA(level - 1);
            addLine(-distribution, 0);
            hilbertA(level - 1);
            addLine(0, distribution);
            hilbertD(level - 1);
        }
    }

}

Once you have the model, you can share it between views, so that they can render it in what ever way they see fit, for example...一旦你有了模型,你就可以在视图之间共享它,这样他们就可以以他们认为合适的任何方式渲染它,例如......

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class Test {

    public class HilbertCurveModel {

        private List<Point> points;
        private int distribution;

        private int xDelta, yDelta;

        public HilbertCurveModel(int level, int size) {
            points = new ArrayList<>(25);
            distribution = size;
            for (int i = level; i > 0; i--) {
                distribution /= 2;
            }
            hilbertU(level);
        }

        public int getDistribution() {
            return distribution;
        }

        public List<Point> getPoints() {
            List<Point> copy = new ArrayList<>(points.size());
            for (Point p : points) {
                copy.add(new Point(p));
            }
            return copy;
        }

        protected void addLine(int x, int y) {
            points.add(new Point(x + xDelta, y + yDelta));
            xDelta += x;
            yDelta += y;
        }

        private void hilbertU(int level) {
            if (level > 0) {
                hilbertD(level - 1);
                addLine(0, distribution);
                hilbertU(level - 1);
                addLine(distribution, 0);
                hilbertU(level - 1);
                addLine(0, -distribution);
                hilbertC(level - 1);
            }
        }

        private void hilbertD(int level) {
            if (level > 0) {
                hilbertU(level - 1);
                addLine(distribution, 0);
                hilbertD(level - 1);
                addLine(0, distribution);
                hilbertD(level - 1);
                addLine(-distribution, 0);
                hilbertA(level - 1);
            }
        }

        private void hilbertC(int level) {
            if (level > 0) {
                hilbertA(level - 1);
                addLine(-distribution, 0);
                hilbertC(level - 1);
                addLine(0, -distribution);
                hilbertC(level - 1);
                addLine(distribution, 0);
                hilbertU(level - 1);
            }
        }

        private void hilbertA(int level) {
            if (level > 0) {
                hilbertC(level - 1);
                addLine(0, -distribution);
                hilbertA(level - 1);
                addLine(-distribution, 0);
                hilbertA(level - 1);
                addLine(0, distribution);
                hilbertD(level - 1);
            }
        }

    }

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

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                HilbertCurveModel model = new HilbertCurveModel(4, 512);

                HilbertCurve exemplo1 = new HilbertCurve(model);
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(exemplo1);
                frame.pack();
                frame.setLocation(100, 100);
                frame.setVisible(true);

                // This is the second window ;)

                int xPos = model.getDistribution() / 2;
                int yPos = model.getDistribution() / 2;

                DefaultListModel listModel = new DefaultListModel();
                listModel.addElement(new Point(xPos, yPos));
                for (Point p : model.getPoints()) {
                    listModel.addElement(p);
                }

                JFrame frame1 = new JFrame();
                frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame1.add(new JScrollPane(new JList(listModel)));
                frame1.pack();
                frame1.setLocation(800, 100);
                frame1.setVisible(true);
            }
        });
    }

    public class HilbertCurve extends JPanel {

        private HilbertCurveModel model;
        private int xPos, yPos;

        public HilbertCurve(HilbertCurveModel model) {
            this.model = model;
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int xPos = model.getDistribution() / 2;
            int yPos = model.getDistribution() / 2;

            List<Point> points = model.points;
            if (points.size() == 0) {
                return;
            }
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.translate(xPos, yPos);
            g2d.setColor(Color.BLACK);
            Point from = new Point(0, 0);
            for (Point point : points) {
                Point to = new Point(point);
                System.out.println(from + "x" + to);
                Line2D line = new Line2D.Double(from, to);
                g2d.draw(line);
                from = to;
            }
            g2d.dispose();
        }
    }
}

This will basically create two windows, one will render the curve and the other will display a list of points这将基本上创建两个窗口,一个将渲染曲线,另一个将显示点列表

Updated更新

The problem about my code is that I have the g.drawLine(x, y, x + deltaX, y + deltaY);关于我的代码的问题是我有 g.drawLine(x, y, x + deltaX, y + deltaY); g.drawString(Integer.toString(a++), x+deltaX, y+deltaY); g.drawString(Integer.toString(a++), x+deltaX, y+deltaY); in the lineRel method, and I don't know how to draw differently in another frame.在 lineRel 方法中,我不知道如何在另一帧中进行不同的绘制。 Every time I call the paint method, it draws the same thing每次我调用paint方法时,它都会绘制相同的东西

Okay, this example goes to the nth degree.好的,这个例子是第 n 级。 Personally, I'd have created a renderer which contained a couple of flags which could be used to turn features on or off, but this demonstrates inheritance and how you might be able to use to use it to expand the functionality of a class.就我个人而言,我已经创建了一个渲染器,其中包含几个可用于打开或关闭功能的标志,但这演示了继承以及您如何使用它来扩展类的功能。

弯曲的

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Test {

    public class HilbertCurveModel {

        private List<Point> points;
        private int distribution;

        private int xDelta, yDelta;

        public HilbertCurveModel(int level, int size) {
            points = new ArrayList<>(25);
            distribution = size;
            for (int i = level; i > 0; i--) {
                distribution /= 2;
            }
            hilbertU(level);
        }

        public int getDistribution() {
            return distribution;
        }

        public List<Point> getPoints() {
            List<Point> copy = new ArrayList<>(points.size());
            for (Point p : points) {
                copy.add(new Point(p));
            }
            return copy;
        }

        protected void addLine(int x, int y) {
            points.add(new Point(x + xDelta, y + yDelta));
            xDelta += x;
            yDelta += y;
        }

        private void hilbertU(int level) {
            if (level > 0) {
                hilbertD(level - 1);
                addLine(0, distribution);
                hilbertU(level - 1);
                addLine(distribution, 0);
                hilbertU(level - 1);
                addLine(0, -distribution);
                hilbertC(level - 1);
            }
        }

        private void hilbertD(int level) {
            if (level > 0) {
                hilbertU(level - 1);
                addLine(distribution, 0);
                hilbertD(level - 1);
                addLine(0, distribution);
                hilbertD(level - 1);
                addLine(-distribution, 0);
                hilbertA(level - 1);
            }
        }

        private void hilbertC(int level) {
            if (level > 0) {
                hilbertA(level - 1);
                addLine(-distribution, 0);
                hilbertC(level - 1);
                addLine(0, -distribution);
                hilbertC(level - 1);
                addLine(distribution, 0);
                hilbertU(level - 1);
            }
        }

        private void hilbertA(int level) {
            if (level > 0) {
                hilbertC(level - 1);
                addLine(0, -distribution);
                hilbertA(level - 1);
                addLine(-distribution, 0);
                hilbertA(level - 1);
                addLine(0, distribution);
                hilbertD(level - 1);
            }
        }

    }

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

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                HilbertCurveModel model = new HilbertCurveModel(4, 512);

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new HilbertCurveLineRenderer(model));
                frame.pack();
                frame.setLocation(100, 100);
                frame.setVisible(true);

                JFrame frame2 = new JFrame();
                frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame2.add(new HilbertCurveLineAndPointRenderer(model));
                frame2.pack();
                frame2.setLocation(100 + frame.getWidth(), 100);
                frame2.setVisible(true);
            }
        });
    }

    public abstract class AbstractHilbertCurve extends JPanel {

        private HilbertCurveModel model;

        public AbstractHilbertCurve(HilbertCurveModel model) {
            this.model = model;
        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int xPos = model.getDistribution() / 2;
            int yPos = model.getDistribution() / 2;

            List<Point> points = model.points;
            if (points.size() == 0) {
                return;
            }
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.translate(xPos, yPos);
            g2d.setColor(Color.BLACK);
            Point from = new Point(0, 0);
            int count = 0;
            for (Point to : points) {
                count++;
                // I don't trust you to play nice with my graphics context
                Graphics2D copyG = (Graphics2D) g2d.create();
                renderLine(copyG, from, to);
                renderCurrentPoint(copyG, count, to);
                from = to;
                copyG.dispose();
            }
            g2d.dispose();
        }

        protected void renderLine(Graphics2D g2d, Point from, Point to) {
        }

        protected void renderCurrentPoint(Graphics2D g2d, int count, Point current) {
        }
    }

    public class HilbertCurveLineRenderer extends AbstractHilbertCurve {

        public HilbertCurveLineRenderer(HilbertCurveModel model) {
            super(model);
        }

        protected void renderLine(Graphics2D g2d, Point from, Point to) {
            Line2D line = new Line2D.Double(from, to);
            g2d.draw(line);
        }
    }

    public class HilbertCurveLineAndPointRenderer extends AbstractHilbertCurve {

        public HilbertCurveLineAndPointRenderer(HilbertCurveModel model) {
            super(model);
        }

        protected void renderLine(Graphics2D g2d, Point from, Point to) {
            Line2D line = new Line2D.Double(from, to);
            g2d.draw(line);
        }

        @Override
        protected void renderCurrentPoint(Graphics2D g2d, int count, Point current) {
            String text = Integer.toString(count);
            FontMetrics fm = g2d.getFontMetrics();
            int x = current.x - (fm.stringWidth(text) / 2); 
            g2d.drawString(text, x, current.y);
        }

    }
}

I would, highly, recommend you take a closer look at How to perform custom painting and Painting in Swing to gain a better understanding into how painting actually works in Swing.我强烈建议您仔细查看如何在 Swing 中执行自定义绘画绘画,以更好地了解绘画在 Swing 中的实际工作原理。

Also, an instance of a component can only reside in one container at a time.此外,一个组件的实例一次只能驻留在一个容器中。 As demonstrated in the above example, you will need at least two instances of the render pane如上例所示,您至少需要渲染窗格的两个实例

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

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