- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我是新来的。希望您能提供帮助。
问题:在 JFrame 上显示动画时出现问题。似乎我想念/不太了解 Java 的图形是如何工作的。
全局理念:假设我想制作游戏/电影/剪辑。为此,我需要这个(不是)简单的动画开始工作。
这个问题的一个例子:我得到了 Screen 类,它具有屏幕内容 - JFrame 的声明,设置其配置(大小,关闭操作等),然后创建 Box 类的对象,以显示在框架上。请检查这张图片/类图(希望我写得正确):ClassesDiagram
现在,Box 类扩展了 JPanel。我从 JPanel 继承了 Paint() 方法并覆盖它,绘制框。
在 Screen 类中,在我创建了两个 Boxes 之后,我将它们添加到 JFrame。接下来,启动一个循环 while(true),并通过让线程 hibernate 该时间来每 200 毫秒更新一次框的位置。(在这种情况下,只是简单的 x++ 或 y++ 取决于哪个框,box1 或 box2)。
主要问题 1): 程序运行并显示 JFrame,但在 JFrame 上它仅显示最后添加的对象/组件- Box。它没有显示另一个。为什么?
我找到了一个话题,How to add multiple components to a JFrame? ,并尝试了 jjnguy 2010 年 11 月 15 日 17:02 投票最多的帖子给出的提示。出于某种奇怪的原因,第一个和第二个提示都不适合我。
主要问题 2): 据我了解,我需要布局管理器。如果我只想在框架上的特定 X、Y 处绘制 (),为什么我需要它?
找到其他帖子(找不到了)+Oracle关于布局的指南,建议我需要考虑使用setLayout(null);我尝试这样做,但又出现了问题。
主要问题 3): JFrame 出现,它只显示 1 个框(绿色框不会出现,无论你做什么。不知道为什么),当它移动时 -它从另一侧被删除。这里:Box Movement
提前感谢您提供的任何帮助、提示和解释!希望帖子清晰、有条理且美观。
public class Screen {
public static void main(String[] args) {
new Screen();
}
private JFrame window;
public Screen() {
window = new JFrame("Multiply components panel");
//window.setLayout(null);
window.setSize(200, 200);
window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Box b1 = new Box(10,10, "box1");
//b1.setBounds(10, 10, 50, 50);
Box b2 = new Box(100,100, "box2");
//b2.setBounds(100, 100, 50, 50);
window.add(b1);
//window.add(b2);
window.setVisible(true);
while (true){
b1.update();
b2.update();
try {
Thread.sleep(200);
} catch (Exception e) {
// TODO: handle exception
}
}
}
}
public class Box extends JPanel{
int x, y, w, h;
private String name;
public Box(int x, int y, String name) {
this.x = x;
this.y = y;
this.w = 100;
this.h = 100;
this.name=name;
}
public void paint(Graphics g){
System.out.println(this.name.equalsIgnoreCase("box1"));
if(this.name.equalsIgnoreCase("box1")){
g.setColor(Color.BLACK);
g.fillRect(x, y, w, h);
}else{
g.setColor(Color.GREEN);
g.fillRect(x, y, w, h);
}
}
public void update() {
if(this.name.equalsIgnoreCase("box1"))
x++;
else
y++;
//this.setBounds(x, y, w, h);
System.out.println("Current "+name+": X: "+x+", Y: "+y+", W: "+w+", H: "+h);
repaint();
}
}
最佳答案
Main Problem 1): The program runs, and shows the JFrame, but on the JFrame it shows only the last added object/component- Box. It doesn't show the other one. Why?
你做的 window.add(b1);
,默认
window.add(b2);JFrame
有BorderLayout
因此,当您执行 add(..)
时,您将替换最后添加的框.
Main Problem 2): As far as I understand, i need layout manager. Why do I need it, if I just want to paint() at specific X,Y on the frame?
如果您使用 JPanel
作为游戏中的对象,这将是唯一一次使用 setLayout(null)
因为我们想要完全控制 JPanel
放置。
Main Problem 3): The JFrame shows up, it shows only 1 box(the green one wont show up, whatever you will do. Don't know why) and when it DOES move- it gets erased from the other side. Here: Box Movement
因为你你这样做g.fillRect(x,y,w,h)
,应该是g.fillRect(0,0,w,h)
其他问题:
1) 我认为你遇到的一个主要问题是:
public class Box extends JPanel{
...
public void paint(Graphics g){
...
}
}
你应该覆盖 paintComponent
的 JPanel
,记得调用super.paintComponent(g)
作为覆盖方法中的第一次调用。
3) 你应该覆盖 getPreferredSize
的 JPanel
并返回与 JPanel
的图像或内容匹配的正确尺寸
4) 不要调用 setSize
在 JFrame
使用正确 Layoutmanager
和/或覆盖 getPreferredSize
必要的容器比简单地调用 pack()
在 JFrame
在将其设置为可见之前。
5) 正如@MadProgrammer 所说,阅读 Concurrency in Swing但基本上所有 Swing 组件都应该通过 SwingUtilities.inokeXXX
在 EDT 上创建/操作 block 。
6) 这样做绝对不好:
while (true){
b1.update();
b2.update();
try {
Thread.sleep(200);
} catch (Exception e) {
// TODO: handle exception
}
}
因为您不仅要创建连续循环,还要调用 Thread.sleep
在您创建 GUI 的线程上,因此似乎会卡住。看看How to use Swing Timers , 另见 this关于上述主题的类似问题。
这是实现了上述修复的代码:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Screen {
private JFrame window;
public static void main(String[] args) {
//creat UI on EDT
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Screen();
}
});
}
public Screen() {
window = new JFrame("Multiply components panel") {
@Override
public Dimension getPreferredSize() {
return new Dimension(600, 400);
}
};
window.setLayout(null);//only reason this is warrented is because its a gmae using JPanels as game objects thus we need full control over its placing
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//changed from DISPOSE to EXIT so Timers will be exited too
final Box b1 = new Box(10, 10, 50, 50, "box1");
final Box b2 = new Box(100, 100, 50, 50, "box2");
window.add(b1);
window.add(b2);
window.pack();
window.setVisible(true);
Timer timer = new Timer(200, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
b1.update();
b2.update();
}
});
timer.setInitialDelay(0);
timer.start();
}
}
class Box extends JPanel {
int x, y, w, h;
private String name;
public Box(int x, int y, int w, int h, String name) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.name = name;
setBounds(x, y, w, h);//let the Box class handle setting the bounds more elegant OOP
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println(this.name.equalsIgnoreCase("box1"));
if (this.name.equalsIgnoreCase("box1")) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, w, h);
} else {
g.setColor(Color.GREEN);
g.fillRect(0, 0, w, h);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(w, h);
}
public void update() {
if (this.name.equalsIgnoreCase("box1")) {
x++;
} else {
y++;
}
this.setBounds(x, y, w, h);//set the new bounds so box may be updated
System.out.println("Current " + name + ": X: " + x + ", Y: " + y + ", W: " + w + ", H: " + h);
revalidate();
repaint();
}
}
最后看看我的教程/代码片段 Game Development Loop, Logic and Collision detection Java Swing 2D .
它拥有开始一个简单的 2D 游戏所需的一切,例如游戏循环、逻辑、像素碰撞检测、动画(即在多个 Sprite 之间交换以创建 Sprite 集的动画)等等,但根本的区别在于使用对象作为游戏实体,即一个类将保存要绘制的对象所需的所有信息,IMO 这就是游戏应该如何完成的,事情可能会变得图形化,并且有许多 JPanel 想知道屏幕肯定会降低整体 FPS
关于Java 游戏开发 : Graphics,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17373979/
我想知道如何在 OCaml 中设置文本大小。我尝试了 Graphics.set_text_size,我猜这应该可以解决问题。 但是无论我输入 set_text_size 200 还是 set_text
我想使用mathematica 为我正在写的书绘制图表。我想在mathematica中画一个图,将其保存为图片,然后将其导入到quarkxpress中,最后将其导出为pdf。 我的问题是最好使用哪种格
在顶层加载 Graphics 模块时,我收到一条错误消息“找不到 graphics.cma”。 我使用的是 OS X,而且我很确定我已经正确安装了 OCaml,因为我已经使用了大约一个月了。所以看起来
我知道 DDS 文件的存在,允许在 as/400 上对显示图形进行编程,但是还有其他方法吗? 具体来说,我想要做的是直接操作终端缓冲区,以便能够显示除文本之外的任何其他内容。例如,终端如下所示: 假设
Graphics.Save 与 Graphics.BeginContainer 有何不同? 最佳答案 看看here : The documentation does not differentiate
由于 Gdiplus::Graphics::DrawGraphics(Graphics*, x, y) 不存在,执行此类操作的最佳方法是什么? 例如,创建一个 Graphics 对象,使用各种 Dra
你能看出这有什么问题吗: (define (box d x1 y1 x2 y2) ( (graphics-draw-line d x1 y
我想编写一个 2D 游戏引擎。我遇到的问题(我不使用opengl之类的东西,所以我用cpu渲染)是,我通过graphics.drawImage()只得到7fps;您有任何加快速度的建议或其他替代方案吗
我在某些代码中发现了渲染错误,并找到了解决方法,但我想知道为什么我会得到不同的行为。在旧代码中,背景(有时)会呈现为白色,尽管在调试时 getBackground() 会返回正确的颜色。 旧代码: @
有谁知道是否有办法(也许通过外部API)将图形绘图/转换为多个图形?这个想法是同时保存 PNG 和 PDF(使用 Java IText 库)。 最佳答案 您可以将 Graphics 对象写入(java
我试图了解如何在英特尔芯片组上以 x86 保护模式绘制简单图形。我已经(有点)知道如何使用 VGA 接口(interface)来做到这一点,并且我正在尝试了解如何使用 G35 Express 来做到这
在我的应用程序中,我生成了一个条形码图像,该图像是根据用户使用 OpenFileDialog 上传的文件中的数据生成的。我的目标是允许用户在屏幕上查看条形码数据和图像本身,打印并使他们能够将两者保存为
我是 Java 新手,我只是想得到一些简单的东西,可能类似于 Zelle's graphics对于Python。 最佳答案 Java 类 Graphics和 Graphics2D应该包含 Zelle
如何将 FMX.Graphics.TBitmap 转换为 VCL.Graphics.TBitmap 或 Vcl.Imaging.PngImage.TPngImage? 我的项目中有FMX表单和VCL表
我需要找到用于间距目的的字体大小,发现这很有帮助:https://docs.oracle.com/javase/tutorial/2d/text/measuringtext.html 但是,我不确定如
我有一点奇怪的错误是由一个看似简单的问题引起的。 在我的源代码中,我尝试使用 QQuickPaintedItem 来呈现 QWidget 派生类 (QPushButton) 的整体外观,然后将其绘制到
我正在尝试通过具有以下规范的设备来解决 Android 应用程序崩溃的问题: Device PAP3400DUO 1 Manufacturer — Android version Android 4.
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 9 年前。 Improve this ques
我有这行代码: mBgTransition = (TransitionDrawable) mSwitchBg.getBackground(); 背景曾经是一个常规的可绘制对象, 但现在是 9 个补丁
当我的应用程序在启动时崩溃时尝试实现自适应图标时出现此错误。 我无法想象为什么会收到此错误,因为在下面错误日志中提到的文件(MainActivity 和 BaseActivity)中,我没有使用Ada
我是一名优秀的程序员,十分优秀!