【问题标题】:Why can't I create a shape on jpanel?为什么我不能在 jpanel 上创建形状?
【发布时间】:2019-09-15 11:15:49
【问题描述】:

我正在使用套接字编程处理 java gui。我想使用从服务器发送的参数在 jframe 上创建 jpanel,并在 jpanel 中创建随机形状。 我使用这个资源来绘制形状:

https://github.com/AugustBrenner/Random-Draw-Shape/blob/master/DrawPanel.java

我在 jframe 中的代码是;

 public void starteGame(String received) {
    gamers.setText(received);



    String[] mParsed = received.split(" ");
    boolean filled = true;
    int width = Integer.parseInt(mParsed[2]);
    int height = Integer.parseInt(mParsed[1]);
    int x1 = Integer.parseInt(mParsed[3]);
    int y1 = Integer.parseInt(mParsed[4]);
    int x2 = Integer.parseInt(mParsed[5]);
    int y2 = Integer.parseInt(mParsed[6]);
    int randomShape = Integer.parseInt(mParsed[7]);
    Color firstColor = new Color(Integer.parseInt(mParsed[8]), true);
    Color secondColor = new Color(Integer.parseInt(mParsed[9]), true);
    boolean cyclic = Boolean.parseBoolean(mParsed[10]);
    switch (randomShape) {
        case 1:
            // add the line to the list of lines to be displayed
            shape = new MyPolygon(x1, y1, x2, y2, firstColor, filled);
            break;
        case 2:
            shape = new MyRectangle(x1, y1, x2, y2, firstColor, filled);
            break;
        case 3:
            shape = new MyOval(x1, y1, x2, y2, firstColor, filled);
            break;
    }

 jPanel2=new PanelDraw(width,height,x1,y1,x2,y2,firstColor,secondColor,
randomShape,shape,cyclic);

}

And my PanelDraw is;
public class PanelDraw extends JPanel implements MouseMotionListener {

private Random randomNumbers;
private MyShape shape;
int x1;
int y1;
int x2;
int y2;
Color firstColor;
Color secondColor;
int width;
int height;
// generate random shape
int randomShape;
 boolean cyclic ;
// constructor, creates a panel with random shapes
public PanelDraw(int width, int height, int x1, int y1, int x2, int y2, 
Color first, Color second, int randomS,MyShape shape ,boolean cyclic) {
    this.width = width;
    this.height = height;
    // generate random coordinates      
    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;
    this.y2 = y2;
    // generate a random color
    this.firstColor = first;
    this.secondColor = second;
    // generate random shape
    randomShape = randomS;
    this.shape=shape;
    this.cyclic=cyclic;
    //setBackground( Color.BLACK ); 
} // end DrawPanel constructor

   public void mouseMoved(MouseEvent event) {

}// end mouseMoved

public void mouseDragged(MouseEvent event) {
} // end method

// for each shape array, draw the individual shapes
   @Override
   public void paintComponent(Graphics g) {

    //initialize filled boolean to true;
    boolean filled = true;

    // initialize random cyclic boolean


    // draw the shape
    Graphics2D g2d = (Graphics2D) g; // cast g to Graphics2D
    g2d.setPaint(new GradientPaint(x1, y1, firstColor, x2, y2,
            secondColor, cyclic));
    shape.draw(g2d);
    g2d.dispose();
   // shapeCount++;

    try {
        Thread.sleep(700);
    } catch (Exception e) {
    }

    repaint();

} // end method paintComponent

} // end class DrawPanel

当我的函数运行时面板没有出现并且随机形状没有出现。 你能帮帮我吗?

【问题讨论】:

    标签: java multithreading swing jpanel


    【解决方案1】:

    问题 #1...

    try {
        Thread.sleep(700);
    } catch (Exception e) {
    }
    

    在您的 paintComponent 方法中:/

    Swing 是单线程的(并且不是线程安全的),在您的 paintComponent 中执行此操作将阻止一切都被绘制,直到 sleep 返回之后,它还将阻止所有用户交互的发生。

    详情请见Concurrency in Swing

    问题 #1.1...

    Graphics2D g2d = (Graphics2D) g; // cast g to Graphics2D
    //...
    g2d.dispose();
    

    传递给您的Graphics 上下文由系统创建,并在绘制过程中被绘制的所有组件之间共享。像这样处理它可能会导致其他组件被绘制

    问题 #1.2...

    repaint();
    

    在您的 paintComponent 方法中。

    不要直接或间接地在绘制过程中更改任何组件的状态。绘画应该描绘状态而不是别的。这样做会导致重绘管理器疯狂运行并消耗所有 CPU 周期

    问题 #2....

    jPanel2=new PanelDraw(width,height,x1,y1,x2,y2,firstColor,secondColor, randomShape,shape,cyclic);
    

    是的,但你没有将组件添加到任何东西,那么它应该如何绘制?

    【讨论】:

    • 谢谢,但我不明白问题 2。我正在等待通过将参数提供给新的 JPanel Draw 来使用 g2d.setPaint 绘制形状。我必须如何发行公司?
    • jpanel 已在 jframe 中定义。我试过 jPanel2.setVisible(true);
    • 但是,根据您的上下文代码,您永远不会将 jPanel2 的新实例添加到任何东西,因此它永远不会被绘制。我“猜测”你真正想要的是一个“模型”,它代表你想要绘制的状态,它在面板和更新过程之间共享。然后可以使用观察者模式,以便面板知道模型何时发生更改并可以重新绘制自身 - 这由“模型-视图-控制器”范式涵盖
    【解决方案2】:
    Thread.sleep(700);
    

    永远不要在绘画方法中使用 Thread.sleep()。

    这将导致事件调度线程休眠,这意味着 GUI 无法重新绘制自身或响应事件。

    还有:

    1. 切勿在绘画方法中调用 reapint()。如果您需要动画,请使用 Swing Timer。

    2. paintCoponent() 方法中的第一条语句应该是super.paintComponent(g),以确保在您进行自定义绘画之前清除面板的背景。

    【讨论】:

      猜你喜欢
      • 2013-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-18
      • 1970-01-01
      • 2019-11-19
      • 1970-01-01
      相关资源
      最近更新 更多