如何在jpanel

时间:2017-04-01 01:00:10

标签: java jpanel

我正在学习java类,我有一个继承相关的问题。我必须实现一个具有各种数字类的系统。超类是数字,子类是Circle,Box和Rectangle,我应该输出JPanel中的数字。我已经设计了所有类,我的代码在下面但是我需要在图类上定义center()方法,当调用对象时应该绘制并擦除对象。所以在JPanel类的main方法中,我想使用center()方法绘制三个形状,并使用wait(long timeout)方法使形状在15秒后变为随机位置。

import java.awt.Graphics;
import javax.swing.JPanel;

public abstract class Figure extends JPanel {

protected int xCoord;
protected int yCoord;

public Figure() {
}

public void erase() {

}

public void draw() {

}

public void center() {

}
}

矩形子类是:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;

public class Rectangle extends Figure {
int width;
int height;

public Rectangle() {

    this.width = 0;
    this.height = 0;
}

public Rectangle(int xCoord, int yCoord, int width, int height)


{
    this.xCoord = xCoord;
    this.yCoord = yCoord;
    this.width = width;
    this.height = height;
}

public void draw(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.BLACK);
    g.fillRect(xCoord, yCoord, width, height);
}

public void erase(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, 0, 0);
}

}

圆圈子类:

public class Circle extends Figure {

private int radius;

 public Circle ()
  {
     this.radius = 0;
  }

 public Circle (int xCoord, int yCoord, int radius)          
  {
     this.xCoord = xCoord;
     this.yCoord = yCoord;
     this.radius = radius;
  }

 public void draw(Graphics g){
      super.paintComponent(g);
      g.setColor(Color.BLACK);
      g.fillOval(xCoord, yCoord, radius, radius);
  }

 public void erase(Graphics g){
      super.paintComponent(g);
      g.setColor(Color.BLACK);
      g.fillOval(0,0,0,0);
  }

}

框子类:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;

public class Box extends Figure {

private int edgeLength;

public Box() {
    this.edgeLength = 0;
}

public Box(int xCoord, int yCoord, int edgeLength)// Creating Rectangle
                                                    // Class given width and
                                                    // height
{
    this.xCoord = xCoord;
    this.yCoord = yCoord;
    this.edgeLength = edgeLength;
}

public void draw(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.BLACK);
    g.fillRect(xCoord, yCoord, edgeLength, edgeLength);
}

public void erase(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, 0, 0);
}

}

JPanel类

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.LayoutManager;
import java.awt.Point;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class SamplePanel extends JPanel {

private static final int PANEL_HEIGHT = 400;
private static final int PANEL_WIDTH = 400;
Rectangle rect = new Rectangle(75, 85, 50,30);
Circle circle = new Circle(275, 75, 50);
Box box = new Box (75, 275, 50);

public SamplePanel() {

    setPreferredSize(new Dimension(PANEL_HEIGHT, PANEL_WIDTH));
    setBackground(Color.WHITE);
    //Rectangle rect = new Rectangle(100, 100, 15,10);
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    rect.draw(g);
    circle.draw(g);
    box.draw(g);
    g.drawLine(200, 0, 200, 400);
    g.drawLine(0, 200, 400, 200);




}

/**
 * @param layout
 */
public SamplePanel(LayoutManager layout) {
    super(layout);
}

/**
 * @param isDoubleBuffered
 */
public SamplePanel(boolean isDoubleBuffered) {
    super(isDoubleBuffered);
}

/**
 * @param layout
 * @param isDoubleBuffered
 */
public SamplePanel(LayoutManager layout, boolean isDoubleBuffered) {
    super(layout, isDoubleBuffered);
}

public static void main(String[] args) {
    JFrame frame = new JFrame("Window Title Here");
    SamplePanel panel = new SamplePanel();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(panel);
    frame.pack();
    frame.setVisible(true);
    Figure box = new Box(75, 275, 50);


}   

}

1 个答案:

答案 0 :(得分:1)

答案...

How to use Swing Timers

在Swing的上下文中使用是安全的,因为它不会在等待时阻塞事件调度线程,并且会在事件调度线程的上下文中生成通知,从而可以安全地更新UI。

观测...

您的基本设计虽然在概念上是正确的,但却是正确实施的。我强烈反对你以这种方式使用JPanel。组件具有特定的生命周期,您无法正确管理,这可能导致问题无法解决。

相反,请回到基础。形状应该是什么样的?

public interface Figure {
    public void draw(Graphics2D g2d);
    public Rectangle getBounds();
    public void setBounds(Rectangle bounds);
}

在这里,它能够被绘制并且具有大小和位置的概念(是的,你可以使用abstract类,但这会删除对基础实现的所有要求,使其更加灵活)

因为我想大多数实现基本相同,我可以使用abstract类来实现核心功能......

public abstract class AbstractFigure implements Figure {
    private Rectangle bounds;

    @Override
    public Rectangle getBounds() {
        return bounds;
    }

    @Override
    public void setBounds(Rectangle bounds) {
        this.bounds = bounds;
    }

}

根据您的需求,您可以创建一些实现不同功能的abstract类,但基本思路是查看所有实现共有的功能并减少重复代码的数量你生成了。

然后你可以开始实现你的具体类......

public class RectangleFigure extends AbstractFigure {

    public RectangleFigure(Rectangle bounds) {
        setBounds(bounds);
    }

    @Override
    public void draw(Graphics2D g2d) {
        g2d.setColor(Color.BLACK);
        g2d.fill(getBounds());
    }

}

但你问的“擦除”方法在哪里?嗯,擦除只是没有绘画,所以,当你想要“擦除”一个形状,从绘画过程中删除它并重新绘制容器,形状被删除

我建议您需要查看Painting in AWT and SwingPerforming Custom Painting,以便更好地了解Swing中的绘画效果。

“中心方法在哪里?”我听你问。好吧,你“可以”在Figure中有一个中心方法,问题是,Figure没有父容器的概念,你是否必须将容器的大小传递给它。不过,我认为这并不困难,这实际上不是Figure的函数,而是容器的函数,所以我在那里实现了中心方法,因为你想改变位置无论如何,Figure s对包裹在容器中的所有东西都有意义(对我而言)