[英]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.