图形未出现在Java Jframe画布中
我试图在一个Jframe中画一个藤蔓,但是当我运行程序时,图形没有出现。这个想法是,一个“藤”是随机产生的,可以随机分支到其他“藤”。如果有人能帮忙,我将不胜感激图形未出现在Java Jframe画布中,java,Java,我试图在一个Jframe中画一个藤蔓,但是当我运行程序时,图形没有出现。这个想法是,一个“藤”是随机产生的,可以随机分支到其他“藤”。如果有人能帮忙,我将不胜感激 import java.awt.Color; import java.awt.Container; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; public class Vine extends JPanel
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Vine extends JPanel {
public void paint(Graphics g, int a, int b, int c)
{
super.paint(g);
g.setColor(Color.BLACK);
g.drawLine(10, 10, 100, 100);
grow(g, a, b, c);
}
public Boolean TF(){
Boolean A;
int B = ((int)Math.random()+1);
if (B==1){
A = true;
} else {
A = false;
}
return A;
}
public void grow(Graphics g, int a, int b, int c){
int x = a;
int y = b;
int age = c;
for (int i=0; i<= age; i++) {
if (TF()) {
if (TF()) {
grow(g, x, y, ((age-i)/2));
}
}
if (TF()){
if (TF()){
g.drawLine(x, y, (x+1), y);
x++;
} else {
g.drawLine(x, y, (x-1), y);
x++;
}
} else {
g.drawLine(x, y, x, (y+1));
y++;
}
}
}
public static void main(String[] args)
{
JFrame f = new JFrame("Vine");
f.setBounds(300, 300, 200, 120);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Vine panel = new Vine();
Container c = f.getContentPane();
panel.setBackground(Color.WHITE);
c.add(panel);
f.setResizable(true);
f.setVisible(true);
}
}
导入java.awt.Color;
导入java.awt.Container;
导入java.awt.Graphics;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类JPanel{
公共空隙油漆(图形g、内部a、内部b、内部c)
{
超级油漆(g);
g、 设置颜色(颜色为黑色);
g、 抽绳(10、10、100、100);
生长(g,a,b,c);
}
公共布尔TF(){
布尔A;
int B=((int)Math.random()+1);
如果(B==1){
A=真;
}否则{
A=假;
}
返回A;
}
公共空间增长(图形g、整数a、整数b、整数c){
int x=a;
int y=b;
int age=c;
对于(int i=0;i,这里有很多实现问题。您可以覆盖JPanel的paintComponent
,在其中进行绘制。下面是一个快速修复程序,演示如何完成此操作。我对您的实现进行了大量更改,以解决这些问题,以便您能够了解情况
注意:这是一个快速解决方案。因此,代码质量较低,一些OOP概念被忽略。只需完成此过程,了解其工作原理并实现您自己的代码
说明:
您必须调用JPanel类的repaint
方法使其自身重新绘制。它也会将LinkedList中的所有行绘制到面板(请参阅实现)。重新绘制后,创建一个新的随机行并将其添加到LinkedList。下次将绘制它
然后我们必须对此设置动画。因此我在Vine
类中实现了runnable
接口。当我们将此Vine对象(面板)添加到线程和start()时,将调用run
方法
线程。我们需要永远运行它。因此,在运行
方法中添加一个循环。然后每次调用运行方法时,重新绘制面板
。此动画太快,因此添加线程.sleep()
以减慢动画速度
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.util.LinkedList;
import javax.swing.JFrame;
import javax.swing.JPanel;
class Line {//Line class to store details of lines
int x1, y1, x2, y2;
public Line(int x1, int y1, int x2, int y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
}
class Vine extends JPanel implements Runnable {//implements runnable to animate it
LinkedList<Line> lines = new LinkedList<>();//LinkedList to store lines
int x = 10;
int y = 10;
Line line;
public Boolean TF() {
Boolean A;
int B = (int) (Math.random() * 2 + 1);//logical error fixed
if (B == 1) {
A = true;
} else {
A = false;
}
return A;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
for (Line line : lines) {//paint all lines in the LinkedList
g.drawLine(line.x1, line.y1, line.x2, line.y2);
}
//Create and add a next line
if (TF()) {
if (TF()) {
line = new Line(x, y, (x + 1), y);
lines.add(line);
x++;
} else {
line = new Line(x, y, (x - 1), y);
lines.add(line);
x++;
}
} else {
line = new Line(x, y, x, (y + 1));
lines.add(line);
y++;
}
}
private static Vine panel;
public static void main(String[] args) {
JFrame f = new JFrame("Vine");
f.setSize(300, 300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new Vine();
Container c = f.getContentPane();
panel.setBackground(Color.WHITE);
c.add(panel);
f.setResizable(true);
f.setVisible(true);
panel.start();//start the animation(thread)
}
private void start() {
Thread thread = new Thread(this);
thread.start();
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(100);//slow down the animation
panel.repaint();//then repaint the panel
} catch (InterruptedException ex) {
}
}
}
}
导入java.awt.Color;
导入java.awt.Container;
导入java.awt.Graphics;
导入java.util.LinkedList;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
类Line{//Line类来存储行的详细信息
int-x1,y1,x2,y2;
公用线路(int x1、int y1、int x2、int y2){
这是1.x1=x1;
这是1.y1=y1;
这是0.x2=x2;
这1.y2=y2;
}
}
类Vine扩展了JPanel implements Runnable{//implements Runnable使其动画化
LinkedList lines=新建LinkedList();//用于存储行的LinkedList
int x=10;
int y=10;
线条;
公共布尔TF(){
布尔A;
int B=(int)(Math.random()*2+1);//修复了逻辑错误
如果(B==1){
A=真;
}否则{
A=假;
}
返回A;
}
@凌驾
受保护组件(图形g){
超级组件(g);
g、 设置颜色(颜色为黑色);
对于(行:行){//绘制LinkedList中的所有行
g、 抽绳(线x1、线y1、线x2、线y2);
}
//创建并添加下一行
if(TF()){
if(TF()){
直线=新线(x,y,(x+1),y);
行。添加(行);
x++;
}否则{
直线=新线(x,y,(x-1),y);
行。添加(行);
x++;
}
}否则{
直线=新线(x,y,x,(y+1));
行。添加(行);
y++;
}
}
私人静电屏;
公共静态void main(字符串[]args){
JFrame f=新的JFrame(“藤”);
f、 设置大小(300300);
f、 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
面板=新藤();
容器c=f.getContentPane();
面板.立根背景(颜色.白色);
c、 添加(面板);
f、 可设置大小(真);
f、 setVisible(真);
panel.start();//启动动画(线程)
}
私有void start(){
螺纹=新螺纹(此);
thread.start();
}
@凌驾
公开募捐{
while(true){
试一试{
Thread.sleep(100);//减慢动画速度
panel.repaint();//然后重新绘制面板
}捕获(中断异常例外){
}
}
}
}
此代码有几个问题:
- 没有人调用
paint(Graphics g,int a,int b,int c)
方法。当您从这样的Swing组件继承时,有几个方法“自动”调用(其中有一个paint(Graphics g)
方法)。但是要执行自定义绘制,通常应覆盖绘制组件(图形g)
方法
- 您正在绘制时生成随机数。这会产生一些奇怪的效果。最明显的效果是:当您调整帧的大小时(或发生导致重新绘制帧的其他情况时),将出现一个新的随机藤蔓。它与前一个藤蔓没有任何共同之处,在最好的情况下,会造成闪烁的混乱
- 为了创建仍然是“随机”的可重复生成的结果,我通常建议不要使用
Math.random()
(事实上,我从来没有使用过它)。java.util.random
类通常更可取。它允许创建可重复的随机数序列(这有助于调试),它提供了方便的方法,如Random 35; nextBoolean()
,这正是您可能希望通过(实现有些奇怪的)TF()
方法实现的效果。这引出了下一点…:
- 使用更好的变量和方法名称。命名变量,如中的
c
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Path2D;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class VinePainting
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
private void createAndShowGUI()
{
JFrame f = new JFrame("Vine");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
VinePanel panel = new VinePanel();
Container c = f.getContentPane();
panel.setBackground(Color.WHITE);
c.add(panel);
f.setSize(500, 500);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}
class VinePanel extends JPanel
{
private static final Random RANDOM = new Random(0);
private Path2D vine;
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
if (vine == null)
{
vine = createVine(getWidth()/2, getHeight());
}
g.setColor(Color.BLACK);
g.draw(vine);
}
private Path2D createVine(int x, int y)
{
Path2D path = new Path2D.Double();
double angleRad = Math.toRadians(-90);
grow(path, x, y, angleRad, 10.0, 0, 30);
return path;
}
private static void grow(Path2D path,
double x, double y, double angleRad,
double stepSize, int step, int steps)
{
if (step == steps)
{
return;
}
path.moveTo(x, y);
double dirX = Math.cos(angleRad);
double dirY = Math.sin(angleRad);
double distance = random(stepSize, stepSize + stepSize);
double newX = x + dirX * distance;
double newY = y + dirY * distance;
path.lineTo(newX, newY);
final double angleRadDeltaMin = -Math.PI * 0.2;
final double angleRadDeltaMax = Math.PI * 0.2;
double progress = (double)step / steps;
double branchProbability = 0.3;
double branchValue = RANDOM.nextDouble();
if (branchValue + 0.1 < branchProbability)
{
double angleRadDelta = random(angleRadDeltaMin, angleRadDeltaMax);
double newAngleRad = angleRad + angleRadDelta;
double newStepSize = (1.0 - progress * 0.1) * stepSize;
grow(path, newX, newY, newAngleRad, newStepSize, step+1, steps);
}
double angleRadDelta = random(angleRadDeltaMin, angleRadDeltaMax);
double newAngleRad = angleRad + angleRadDelta;
double newStepSize = (1.0 - progress * 0.1) * stepSize;
grow(path, newX, newY, newAngleRad, newStepSize, step+1, steps);
}
private static double random(double min, double max)
{
return min + RANDOM.nextDouble() * (max - min);
}
}
package com.ggl.testing;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Vine implements Runnable {
@Override
public void run() {
JFrame frame = new JFrame("Vine");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawingPanel panel = new DrawingPanel(400, 400);
frame.add(panel);
frame.pack();
frame.setVisible(true);
new GrowVine(panel, 400, 400).run();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Vine());
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = -8460577623396871909L;
private List<LineSegment> lineSegments;
public DrawingPanel(int width, int height) {
this.setPreferredSize(new Dimension(width, height));
this.lineSegments = new ArrayList<>();
}
public void setLineSegments(List<LineSegment> lineSegments) {
this.lineSegments = lineSegments;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
for (int i = 0; i < lineSegments.size(); i++) {
LineSegment ls = lineSegments.get(i);
Point s = ls.getStartPoint();
Point e = ls.getEndPoint();
g.drawLine(s.x, s.y, e.x, e.y);
}
}
}
public class GrowVine implements Runnable {
private int width;
private int height;
private DrawingPanel drawingPanel;
private List<LineSegment> lineSegments;
public GrowVine(DrawingPanel drawingPanel, int width, int height) {
this.drawingPanel = drawingPanel;
this.lineSegments = new ArrayList<>();
lineSegments.add(new LineSegment(10, 10, width - 10, height - 10));
this.width = width;
this.height = height;
}
@Override
public void run() {
grow(width / 2, height / 2, 200);
drawingPanel.setLineSegments(lineSegments);
}
public void grow(int a, int b, int c) {
int x = a;
int y = b;
int age = c;
for (int i = 0; i <= age; i++) {
if (coinFlip()) {
if (coinFlip()) {
grow(x, y, ((age - i) / 2));
}
}
if (coinFlip()) {
if (coinFlip()) {
lineSegments.add(new LineSegment(x, y, (x + 1), y));
x++;
} else {
lineSegments.add(new LineSegment(x, y, (x - 1), y));
x++;
}
} else {
lineSegments.add(new LineSegment(x, y, x, (y + 1)));
y++;
}
}
}
private boolean coinFlip() {
return Math.random() < 0.50D;
}
}
public class LineSegment {
private final Point startPoint;
private final Point endPoint;
public LineSegment(int x1, int y1, int x2, int y2) {
this.startPoint = new Point(x1, y1);
this.endPoint = new Point(x2, y2);
}
public Point getStartPoint() {
return startPoint;
}
public Point getEndPoint() {
return endPoint;
}
}
}