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

时间:2018-02-15 02:20:40

标签: java jframe jpanel graphics2d jawt

我的目标是在一帧中实现空间填充曲线,在另一帧中实现每个像素的数量。将来,我需要在第三帧中绘制一些坐标。我现在的问题是如何在一帧中绘制曲线而在另一帧中绘制像素。我只把它们放在同一帧中。

以下是代码:

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);
    }
}

}

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;
    }
}

输出为:Output

我想要的输出是:enter image description here

1 个答案:

答案 0 :(得分:1)

基本上,您希望从视图中分离数据。 “可能”呈现数据的方式应该与数据无关。

这个概念通常被称为“模型 - 视图 - 控制器”。

首先,你想要创建一个“希尔伯特曲线”的模型,它将是一堆点,每个点代表曲线中的下一个点,例如......

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);
        }
    }

}

拥有模型后,您可以在视图之间共享它,以便它们能够以他们认为合适的方式呈现它,例如......

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();
        }
    }
}

这基本上会创建两个窗口,一个将渲染曲线,另一个将显示一个点列表

更新

  

关于我的代码的问题是我有g.drawLine(x,y,x + deltaX,y + deltaY); g.drawString(Integer.toString(a ++),x + deltaX,y + deltaY);在lineRel方法中,我不知道如何在另一帧中绘制不同的方法。每当我调用paint方法时,它都会绘制相同的东西

好的,这个例子是第n级。就个人而言,我已经创建了一个渲染器,其中包含一些可用于打开或关闭功能的标志,但这表明继承以及您可以如何使用它来扩展类的功能。 / p>

Curvy

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);
        }

    }
}

我强烈建议您仔细查看How to perform custom paintingPainting in Swing ,以便更好地了解绘画在Swing中的实际效果。

此外,组件的实例一次只能驻留在一个容器中。如上例所示,您至少需要两个渲染窗格实例