- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我必须使用 Swing 创建 Sierpinski 垫片的实现。我不能使用递归或三角形。我必须使用以下内容算法:
Pick 3 points to define a triangle.
Select one of the vertices as current Loop 50,000 times: Randomly choose a vertex as the target. Draw a pixel at the mid-point between the target and current. Make current the mid-point.
下图中是我有时在编译时得到的结果,但有时它会弹出然后消失,或者根本不显示。如果它确实出现,然后我调整窗口大小,它就会消失(我不关心这个,但如果它有帮助的话。)我有时只能在编译时生成下面的图像(大约 1/3 的时间。)下图是我的代码,分为两类。
import java.awt.*;
import javax.swing.JFrame;
public class SierpinskiGasket {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("SierpinskiGasket");
frame.setSize(630,580);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawSierpinski Sierpinski = new drawSierpinski();
frame.add(Sierpinski);
frame.setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
public class drawSierpinski extends JPanel{
Point point1 = new Point(10,550),
point2 = new Point(300,30),
point3 = new Point(600,555),
current = point1, target;
private int count = 0;
public void paintComponent(Graphics g){
super.paintComponent(g);
while(count<= 50000){
int choice = (int)(Math.random()*3);
switch(choice){
case 0: target = point1; break;
case 1: target = point2; break;
case 2: target = point3; break;
default: System.exit(0);
}
current = midpoint(current,target);
g.drawLine(current.x,current.y,current.x,current.y);
count++;
}
}
public Point midpoint(Point a, Point b){
return new Point((Math.round(a.x+b.x)/2),
(Math.round(a.y+b.y)/2));
}
}
我假设它与 Swing 的多线程处理方式有关,但不幸的是我对如何修复它没有太多了解。非常感谢您的帮助!
最佳答案
这个循环:
while(count<= 50000) {
// ....
}
可能需要一段时间才能完成,同时它将在最关键的时刻(绘图时)完全阻塞 Swing 事件线程。更重要的是,任何微不足道的重新绘制都会触发循环重新运行,再次完全卡住您的 GUI。
解决方案:在paintComponent 之外进行绘图。相反,创建一个 JPanel 大小的 BufferedImage,获取图像的 Graphics 对象,在 BufferedImage 中为三角形绘制随机点,然后在 JPanel 的 PaintComponent 方法中显示该图像。您可以在程序启动时绘制图像,然后在完成后启动 GUI,或者您可以启动 GUI 并在后台线程中绘制到 BufferedImage,并在完成后显示它,两者都可以(如果这是你的 GUI 唯一应该做的事情)。
例如:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class SierpTest {
public static final int BI_WIDTH = 630;
public static final int BI_HEIGHT = 580;
public static void main(String[] args) {
// do this stuff off the swing event thread
final BufferedImage sierpImg = new BufferedImage(BI_WIDTH, BI_HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics g = sierpImg.getGraphics();
// draw triangle with g here
g.dispose(); // always dispose of any Graphics you create yourself
// do this on the Swing event thread
SwingUtilities.invokeLater(() -> {
SierpPanel sierpPanel = new SierpPanel(sierpImg); // pass in image
JFrame frame = new JFrame("Siep Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(sierpPanel);
frame.pack(); // size it to the size of the JPanel
frame.setLocationRelativeTo(null); // center it
frame.setVisible(true);
});
}
}
class SierpPanel extends JPanel {
private BufferedImage img = null;
public SierpPanel(BufferedImage img) {
this.img = img;
}
// so that JPanel sizes itself with the image
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet() || img == null) {
return super.getPreferredSize();
}
return new Dimension(img.getWidth(), img.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
}
例如:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class SierpTest {
public static final int BI_WIDTH = 630;
public static final int BI_HEIGHT = 580;
private static final int MAX_COUNT = 100000;
public static void main(String[] args) {
// do this stuff off the swing event thread
Point point1 = new Point(10, 550);
Point point2 = new Point(300, 30);
Point point3 = new Point(600, 555);
Point current = point1;
Point target = current;
int count = 0;
final BufferedImage sierpImg = new BufferedImage(BI_WIDTH, BI_HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics g = sierpImg.getGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, BI_WIDTH, BI_HEIGHT);
g.setColor(Color.BLACK);
while (count <= MAX_COUNT) {
int choice = (int) (Math.random() * 3);
switch (choice) {
case 0:
target = point1;
break;
case 1:
target = point2;
break;
case 2:
target = point3;
break;
default:
System.exit(0);
}
current = midpoint(current, target);
g.drawLine(current.x, current.y, current.x, current.y);
count++;
}
// draw triangle with g here
g.dispose(); // always dispose of any Graphics you create yourself
// do this on the Swing event thread
SwingUtilities.invokeLater(() -> {
SierpPanel sierpPanel = new SierpPanel(sierpImg); // pass in image
JFrame frame = new JFrame("Siep Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(sierpPanel);
frame.pack(); // size it to the size of the JPanel
frame.setLocationRelativeTo(null); // center it
frame.setVisible(true);
});
}
public static Point midpoint(Point a, Point b) {
return new Point((Math.round(a.x + b.x) / 2), (Math.round(a.y + b.y) / 2));
}
}
class SierpPanel extends JPanel {
private BufferedImage img = null;
public SierpPanel(BufferedImage img) {
this.img = img;
}
// so that JPanel sizes itself with the image
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet() || img == null) {
return super.getPreferredSize();
}
return new Dimension(img.getWidth(), img.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
}
}
}
请注意,如果您想在创建三角形时获得奇特效果并延迟绘制三角形,请考虑使用 Swing Timer 或 SwingWorker。
关于java - Java Swing 中的 Sierpinski Gasket 实现仅有时出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38668266/
所以我必须使用 Swing 创建 Sierpinski 垫片的实现。我不能使用递归或三角形。我必须使用以下内容算法: Pick 3 points to define a triangle. Selec
我是一名优秀的程序员,十分优秀!