簡體   English   中英

如何在兩個不同的 JFrame 中繪制

[英]How to draw in two different JFrames

我的目標是在一幀中實現空間填充曲線,在另一幀中實現每個像素的數量。 將來,我需要在第三幀中繪制一些坐標。 我現在的問題是如何在一幀中繪制曲線而在另一幀中繪制像素。 我只把它們放在同一個框架中。

這是代碼:

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

輸出為:輸出

我想要的輸出是:在此處輸入圖像描述

基本上來說,您希望將數據與視圖分離。 數據“可能”呈現的方式應該與數據無關。

這個概念通常被稱為“模型-視圖-控制器”。

首先,您想創建一個“希爾伯特曲線”模型,這將是一堆點,每個點代表曲線中的下一個點,例如......

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 級。 就我個人而言,我已經創建了一個渲染器,其中包含幾個可用於打開或關閉功能的標志,但這演示了繼承以及您如何使用它來擴展類的功能。

彎曲的

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

    }
}

我強烈建議您仔細查看如何在 Swing 中執行自定義繪畫繪畫,以更好地了解繪畫在 Swing 中的實際工作原理。

此外,一個組件的實例一次只能駐留在一個容器中。 如上例所示,您至少需要渲染窗格的兩個實例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM