- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是一名大学生,我的作业遇到了问题。通常情况下,我会去实验室问问助教,但他整个星期都在生病,所以我们没有任何实验室时间,这个作业要在周一交!
我遇到的具体问题与创建一个显示带有按钮的框架的 Java 应用程序有关,该按钮允许用户创建一个开始在屏幕上弹跳并从框架边界反弹的球。
之前作业中的一个练习是创建一个类似的程序,但运行时会立即显示一个球弹跳。 (我开始工作了)现在,我们必须修改我们的代码并合并允许我们创建多个球的按钮。
起初,我认为这将是一个简单的修改,但现在我对如何实际实例化 Ball 对象感到困惑。我的想法是,我首先必须使 ReboundPanel 和按钮面板出现(可行),然后每当用户按下按钮时,都会实例化一个新的 Ball 对象并显示在 ReboundPanel 上。 (目前不起作用)
感谢大家的帮助!
主程序:
import java.awt.*;
public class Rebound {
public static void main(String[] args) {
JFrame frame = new JFrame ("Rebound");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
JPanel reboundPanel = new ReboundPanel();
JPanel buttonPanel = new ButtonPanel();
frame.getContentPane().add(reboundPanel);
frame.getContentPane().add(buttonPanel);
frame.pack();
frame.setVisible(true);
}
}
应该出现球的面板:
import java.awt.*;
public class ReboundPanel extends JPanel {
private final int WIDTH = 400, HEIGHT = 300;
public ReboundPanel() {
setPreferredSize (new Dimension(WIDTH, HEIGHT));
setBackground (Color.black);
}
}
按钮面板:
import java.awt.*;
public class ButtonPanel extends JPanel {
private final int WIDTH = 400, HEIGHT = 35;
public ButtonPanel() {
setPreferredSize (new Dimension(WIDTH, HEIGHT));
setBackground (Color.GRAY);
JButton button = new JButton("New ball");
add(button);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
new Ball();
}
});
}
}
球类:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Ball extends JPanel {
private final int DELAY = 20, IMAGE_SIZE = 35;
private ImageIcon image;
private Timer timer;
private int x, y, moveX, moveY;
public Ball() {
timer = new Timer(DELAY, new ReboundListener());
image = new ImageIcon ("/src/pa1/images/earth.gif");
x = 0;
y = 40;
moveX = moveY = 3;
draw(null);
timer.start();
}
public void draw(Graphics page) {
super.paintComponent (page);
image.paintIcon (new ReboundPanel(), page, x, y);
}
private class ReboundListener implements ActionListener {
public void actionPerformed (ActionEvent event) {
x += moveX;
y += moveY;
if (x <= 0 || x >= WIDTH-IMAGE_SIZE)
moveX = moveX * -1;
if (y <= 0 || x >= WIDTH-IMAGE_SIZE)
moveY = moveY * -1;
repaint();
}
}
}
最佳答案
考虑您的应用程序元素之间的关系,并让它帮助形成您的类和对象设计。
描述:
应用程序将有一个窗口,其中包含一个按钮和一个容器区域,用于容纳 0 个或多个球。单击按钮时,应将一个新球添加到容器中。球应以固定速度围绕其容器移动并弹离容器的边界。
设计:
这个描述告诉我们很多关于如何构建代码的信息。我们有一些名词:(应用程序)、窗口、按钮、容器、边界和球。我们有一些动词:(have, contains, hold, add), move[ball], bounce[ball], click[button]。
名词暗示可能要实现的类。以及在关联类中实现的可能方法的动词。
让我们创建一个类来表示窗口并将其命名为 Rebound,一个类表示名为 BallPanel 的容器,一个类表示一个名为 Ball 的球。在这种情况下,窗口和应用程序可以被认为是相同的。事实证明,无需为其创建单独的类,即可巧妙地实现该按钮。而且边界很简单,可以用整数表示。
上面我刚刚解释了一种有助于澄清问题的方法,下面我将提供一种可能的实现方式。这些旨在提供一些指导性提示以帮助您理解。您可以通过多种方式分析此问题或实现解决方案,希望这些对您有所帮助。
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Rebound extends JFrame {
/* Milliseconds between each time balls move */
static final int MOVE_DELAY = 20;
/* The JButton for adding a new ball. An AbstractAction
* provides a neat way to specify the label and on-click
* code for the button inline */
JButton addBallButton = new JButton(new AbstractAction("Add ball") {
public void actionPerformed(ActionEvent e) {
ballContainer.addBall();
}
});
/* The Panel for holding the balls. It will need to
* keep tracks of each ball, so we'll make it a subclass
* of JPanel with extra code for the ball management (see
* the definition, after the end of the Rebound class) */
BallPanel ballContainer = new BallPanel();
public Rebound() {
super("Rebound");
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
/* There was no neat way to specify the button size
* when we declared it, so let's do that now */
addBallButton.setPreferredSize(new Dimension(400, 35));
/* Add the components to this window */
getContentPane().add(addBallButton);
getContentPane().add(ballContainer);
pack();
/* Create a timer that will send an ActionEvent
* to our BallPanel every MOVE_DELAY milliseconds */
new Timer(MOVE_DELAY, ballContainer).start();
}
/* The entry point for our program */
public static void main(String[] args) {
/* We use this utility to ensure that code
* relating to Swing components is executed
* on the correct thread (the Swing event
* dispatcher thread) */
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Rebound().setVisible(true);
}
});
}
}
/* Our subclass of JPanel that also manages a list of
* balls. It implements ActionListener so that it can
* act on the Timer event we set up in the Rebound class */
class BallPanel extends JPanel implements ActionListener {
/* An automatically expanding list structure that can
* contain 0 or more Ball objects. We'll create a Ball
* class to manage the position, movement and draw code
* for each ball. */
List<Ball> balls = new ArrayList<Ball>();
/* Let's add some code that will be run
* when the panel is resized (which will happen
* if its window is resized.) We need to make sure
* that each Ball is told about the new bounds
* of the component, so it knows that the place
* where it should bounce has changed */
public BallPanel() {
super();
setPreferredSize(new Dimension(400,300));
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
if (BallPanel.this == e.getComponent()) {
for (Ball ball : balls) {
ball.setBounds(getWidth(), getHeight());
}
}
}
});
}
/* This method is part of the JPanel class we are subclassing.
* Here we change the implementation of the method, ensuring
* we call the original implementation so that we are only
* adding to what it does. */
public void paintComponent(Graphics g) {
/* Call the original implementation of this method */
super.paintComponent(g);
/* Lets draw a black border around the bounds of the component
* to make it clear where the balls should rebound from */
g.drawRect(0,0,getWidth(),getHeight());
/* Now lets draw all the balls we currently have stored in
* our list. */
for (Ball ball : balls) {
ball.draw(g);
}
}
/* This method will add a new Ball into our list. Remember
* from earlier that we call this when our button is clicked. */
public void addBall() {
balls.add(new Ball(this,10,10,getWidth(),getHeight()));
}
/* This method will receive the event from Timer we set up in
* the Rebound class. We want it to cause all the ball to
* move to their next position. */
public void actionPerformed(ActionEvent e) {
for(Ball ball : balls) {
ball.move();
}
/* Request that Swing repaints this JPanel. This should
* cause the paintComponent() method we implemented
* above to be called soon after. */
repaint();
}
}
/* This is our class for keeping track of an individual ball
* and it's position, movement and how it is drawn. */
class Ball {
/* Let's say all balls will have the same diameter of 35.
* The static modifier says that this is a value
* that is shared by all instances of Ball. */
static final int SIZE = 35;
/* Let's say all balls will have a speed in both the X and Y
* axes of 3. The static modifier says that this is a value
* that is shared by all instances of Ball. */
static final int SPEED = 3;
/* Each ball needs to know its position, which we will store
* as x and y coordinates in 2D space */
int x, y;
/* Each ball needs to know the bounds in which it lives, so
* it knows when to bounce. We'll be assuming the minimum
* bound is 0,0 in 2D space. The maximum bound will be
* maxX,mayY in 2D space. We could have made these static
* and shared by all balls, but that means we would have
* to remember to change them to not be static if in the
* future we wanted Ball to be used on more than one JPanel.
* If we didn't remember, then we'd see some buggy behaviour. */
int maxX, maxY;
/* Each ball needs to know its current speed in the X and Y
* directions. We can use positive and negative values to
* keep track of the direction of the ball's movement. */
int speedX = SPEED, speedY = SPEED;
/* Each ball needs to know which panel it is being drawn to
* (this is needed by ImageIcon#drawImage()). */
JPanel panel;
public Ball(JPanel panel, int x, int y, int maxX, int maxY) {
this.x = x; this.y = y;
this.maxX = maxX; this.maxY = maxY;
this.panel = panel;
}
public void setBounds(int maxX, int maxY) {
this.maxX = maxX; this.maxY = maxY;
}
/* This method updates the position of this ball, using
* the current speed and bounds to work out what the new
* position should be.
* This should be called by our BallPanel#actionPerformed()
* method in response to the Timer we set up in the Rebound
* class. */
public void move() {
x += speedX;
y += speedY;
// Approx bounce, okay for small speed
if (x<0) { speedX=-speedX; x=0; }
if (y<0) { speedY=-speedY; y=0; }
if (x+SIZE>maxX) { speedX=-speedX; x=maxX-SIZE; }
if (y+SIZE>maxY) { speedY=-speedY; y=maxY-SIZE; }
}
/* This method is responsible for drawing this ball on
* the provided graphics context (which should come from
* the JPanel associated with the ball). We also have
* the panel, should we need it (ImageIcon#drawImage() needs
* this, but Graphics#drawOval() does not.)
*/
public void draw(Graphics g) {
//image.paintIcon(panel, g, x, y); - commented out because I don't have an ImageIcon
g.drawOval(x, y, SIZE, SIZE);
}
}
关于java - 如何将同一类的多个对象绘制到一个 JPanel 上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9327244/
我的一位教授给了我们一些考试练习题,其中一个问题类似于下面(伪代码): a.setColor(blue); b.setColor(red); a = b; b.setColor(purple); b
我似乎经常使用这个测试 if( object && object !== "null" && object !== "undefined" ){ doSomething(); } 在对象上,我
C# Object/object 是值类型还是引用类型? 我检查过它们可以保留引用,但是这个引用不能用于更改对象。 using System; class MyClass { public s
我在通过 AJAX 发送 json 时遇到问题。 var data = [{"name": "Will", "surname": "Smith", "age": "40"},{"name": "Wil
当我尝试访问我的 View 中的对象 {{result}} 时(我从 Express js 服务器发送该对象),它只显示 [object][object]有谁知道如何获取 JSON 格式的值吗? 这是
我有不同类型的数据(可能是字符串、整数......)。这是一个简单的例子: public static void main(String[] args) { before("one"); }
嗨,我是 json 和 javascript 的新手。 我在这个网站找到了使用json数据作为表格的方法。 我很好奇为什么当我尝试使用 json 数据作为表时,我得到 [Object,Object]
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我听别人说 null == object 比 object == null check 例如: void m1(Object obj ) { if(null == obj) // Is thi
Match 对象 提供了对正则表达式匹配的只读属性的访问。 说明 Match 对象只能通过 RegExp 对象的 Execute 方法来创建,该方法实际上返回了 Match 对象的集合。所有的
Class 对象 使用 Class 语句创建的对象。提供了对类的各种事件的访问。 说明 不允许显式地将一个变量声明为 Class 类型。在 VBScript 的上下文中,“类对象”一词指的是用
Folder 对象 提供对文件夹所有属性的访问。 说明 以下代码举例说明如何获得 Folder 对象并查看它的属性: Function ShowDateCreated(f
File 对象 提供对文件的所有属性的访问。 说明 以下代码举例说明如何获得一个 File 对象并查看它的属性: Function ShowDateCreated(fil
Drive 对象 提供对磁盘驱动器或网络共享的属性的访问。 说明 以下代码举例说明如何使用 Drive 对象访问驱动器的属性: Function ShowFreeSpac
FileSystemObject 对象 提供对计算机文件系统的访问。 说明 以下代码举例说明如何使用 FileSystemObject 对象返回一个 TextStream 对象,此对象可以被读
我是 javascript OOP 的新手,我认为这是一个相对基本的问题,但我无法通过搜索网络找到任何帮助。我是否遗漏了什么,或者我只是以错误的方式解决了这个问题? 这是我的示例代码: functio
我可以很容易地创造出很多不同的对象。例如像这样: var myObject = { myFunction: function () { return ""; } };
function Person(fname, lname) { this.fname = fname, this.lname = lname, this.getName = function()
任何人都可以向我解释为什么下面的代码给出 (object, Object) 吗? (console.log(dope) 给出了它应该的内容,但在 JSON.stringify 和 JSON.parse
我正在尝试完成散点图 exercise来自免费代码营。然而,我现在只自己学习了 d3 几个小时,在遵循 lynda.com 的教程后,我一直在尝试确定如何在工具提示中显示特定数据。 This code
我是一名优秀的程序员,十分优秀!