【问题标题】:How to display a graphic from another class如何显示另一个类的图形
【发布时间】:2019-09-07 01:24:31
【问题描述】:

我正在尝试在我的主类的 JPanel 上显示来自单独类的图形。

主类是 mytest,单独的类是 Ball。 Ball 有一个paint 组件方法,简单地绘制一个彩色圆圈。在 mytest 中,我实例化了一个球并将其添加到 JPanel (dp):dp.add(ball)。很简单,但我得到的只是白色面板背景,没有绘制任何球。

这是我的测试代码:

package myStuff;

import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class mytest {
    private JFrame frame=new JFrame();
    private JPanel dp = new JPanel();


    public static void main(String[] args) {
        mytest gui = new mytest();
        gui.go();
    }
    public void go() {      
        frame.setTitle("Test");
        frame.setSize(1000,600);        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel dp=new JPanel();
        dp.setBackground(Color.WHITE);
        Ball ball = new Ball(dp.getWidth(),dp.getHeight());
        dp.add(ball);
        frame.add(dp);
        frame.setVisible(true);
    }
}

这是类 Ball 代码:

package myStuff;

import java.awt.*;
import javax.swing.*;

public class Ball extends JComponent{

    private int Width; 
    private int Height; 
    public Ball (int width, int height ) {
        Width=width;
        Height=height;      
    }

    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        super.paintComponent(g2d);
        g2d.setColor(Color.RED);
        g2d.fillOval(Width/2,Height/2,40,40);
        System.out.println("Doing graphics....");
    }
}

一个红球应该出现在 dp 面板上。我得到的只是面板背景,没有球。我知道它正在尝试,因为“做图形”打印了两次。

【问题讨论】:

  • 我刚刚注意到我添加了两次 JPanel dp。我从 go() 中取出了它,但它没有任何区别......仍然没有球。
  • Ball 可能不应该是 JComponent,而只是知道如何在请求时绘制自己。绘制它的组件可能是TennisCourtGolfCourse 等,可以包含对BallPaddleNet 等一个或多个实例的引用。

标签: java swing graphics awt


【解决方案1】:

您正在设置框架的大小,但面板的大小为零。您应该设置面板的首选大小,而不是框架的大小。然后获取面板的首选大小以传递给 Ball 构造函数,并在使其可见之前打包框架。

【讨论】:

  • 好的,我做了所有这些并添加了打印语句以验证尺寸是否已通过并且它们已通过。我仍然得到一个白色的背景,没有球。
【解决方案2】:

设置行前面板大小,

Ball ball = new Ball(dp.getWidth(),dp.getHeight());

然后添加这段代码

setPreferredSize(new Dimension(Width, Height));

在“Ball”构造函数的末尾。

请参阅此stack question 了解更多详情。

【讨论】:

  • 我都做到了。仍然没有得到一个球。
  • dp.setBackground(Color.WHITE);维度 d=新维度(800,400); dp.setPreferredSize(d);球球 = 新球(dp.getPreferredSize()); dp.add(球);框架.add(dp);框架.pack(); frame.setVisible(true);
  • 公共球(尺寸 d){ Width=(int)d.getHeight();高度=(int)d.getWidth(); System.out.println(Height +" "+Width); }
  • 在您的原始代码中进行以下更改。使用 dp.setSize() 方法设置面板大小。然后只需添加这一行 setPreferredSize(new Dimension(Width, Height));与原始代码中构造函数末尾的完全相同。
【解决方案3】:

这是一个工作示例。

import java.awt.*;
import javax.swing.*;

public class Mytest {
   private JFrame frame = new JFrame();

   public static void main(String[] args) {
      Mytest gui = new Mytest();
      SwingUtilities.invokeLater(() -> gui.go());
   }

   public void go() {
      frame.setTitle("Test");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      JPanel dp = new JPanel();
      dp.setPreferredSize(new Dimension(500, 500));
      dp.setBackground(Color.WHITE);
      Ball ball = new Ball(150, 150);
      dp.add(ball);
      frame.add(dp);
      frame.pack(); // invokes layout and sizes components
      frame.setLocationRelativeTo(null); // centers on screen
      frame.setVisible(true);
   }

}

class Ball extends JComponent {

   private int width;
   private int height;

   // A ball should probably only have a "diameter"
   public Ball(int width, int height) {
      this.width = width;
      this.height = height;
      setPreferredSize(new Dimension(width, height));
   }

   @Override
   public void paintComponent(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
      super.paintComponent(g2d);
      g2d.setColor(Color.RED);
      // smooths out the graphics
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
      g2d.fillOval(0, 0, width, height);
      System.out.println("Doing graphics....");
   }
}

两个最大的建议是:

  1. 确保在更改 Swing 组件时,您是在 Event Dispatch Thread 上进行的。
  2. 并使用抗锯齿使您的绘图看起来更平滑(注意这是可选的,它会增加额外的处理开销。)

没有绘制红球的原因(或只有 1/4)是因为您更改了在组件窗口中绘制它的位置。您尝试在组件中心的 width/2 和 height/2 处绘制它。正常渲染应该是 0,0。

还可以阅读 Java 教程中的绘画1

【讨论】:

  • 哇....它奏效了。我刚刚错过了将首选尺寸添加到球类中。一旦我这样做了,我得到了一个漂亮的红球!非常感谢你帮助我。我学到了很多东西。你们太棒了!再次感谢。
  • 为什么 Ball 有字段 "width" 和 "height" ?它们隐藏了 Component 超类中已经存在的字段。
  • 那是因为,当我第一次开始这一切时,我想我必须发送面板的大小。猜猜我现在真的不需要它们了!感谢您指出这一点;)
  • 我不会担心的。要知道所有继承的超类字段并不容易。甚至 JComponent 在本地上下文中重新定义高度也会被标记为隐藏超类字段。
  • 感谢 jim829。如果查看修改后的代码,构造函数中传递的宽度和高度实际上是球的宽度和高度。我更改了 Ball 类代码,让球随机选择它的大小。所以我回到了一个空的构造函数 Ball()。再次感谢。一切正常!
猜你喜欢
  • 2020-07-24
  • 2014-08-16
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
  • 2017-03-12
  • 2019-09-05
  • 1970-01-01
  • 2021-09-01
相关资源
最近更新 更多