[英]Displaying a count using JLabel?
My project has classes Car
and Truck
that inherit from abstract class Vehicle
. 我的项目有从abstract class Vehicle
继承的Car
和Truck
abstract class Vehicle
。 Then at random a car or vehicle is to be drawn a total of 10 times. 然后,随机抽取汽车或车辆总共10次。 Also, a count of how many of each is to be displayed in a JLabel
, but my counts keep showing up as 0 in the JFrame
. 另外,在JLabel
中将显示每个计数的计数,但是我的计数在JFrame
始终显示为0。 Here is my code. 这是我的代码。
package vehiclePackage;
import java.awt.Graphics;
import java.util.Random;
public abstract class Vehicle
{
public Vehicle() {
}
public Vehicle(int xLeft, int yTop) {
}
public abstract void draw(Graphics g2);
}
Car
Class: Car
类:
package vehiclePackage;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.Random;
public class Car extends Vehicle
{
private int xLeft;
private int yTop;
private int ccount;
public Car() { }
public Car (int x, int y)
{
super(x,y);
this.xLeft = x;
this.yTop = y;
}
//@override
public void draw(Graphics g2)
{
Random rand = new Random();
float red = rand.nextFloat();
float green = rand.nextFloat();
float blue = rand.nextFloat();
Color randomColor = new Color(red, green, blue);
Rectangle body = new Rectangle (xLeft, yTop +10, 60, 10);
Ellipse2D.Double frontTire = new Ellipse2D.Double (xLeft+10, yTop+20, 10, 10);
Ellipse2D.Double rearTire = new Ellipse2D.Double (xLeft+40, yTop+20, 10, 10);
Point2D.Double r1 = new Point2D.Double(xLeft+10, yTop+10);
Point2D.Double r2 = new Point2D.Double(xLeft+20, yTop);
Point2D.Double r3 = new Point2D.Double(xLeft+40, yTop);
Point2D.Double r4 = new Point2D.Double(xLeft+50, yTop+10);
Line2D.Double frontWindshield = new Line2D.Double(r1,r2);
Line2D.Double roofTop = new Line2D.Double(r2,r3);
Line2D.Double rearWindshield = new Line2D.Double(r3,r4);
((Graphics2D) g2).setColor(randomColor);
((Graphics2D) g2).fill(body);
((Graphics2D) g2).fill(frontTire);
((Graphics2D) g2).fill(rearTire);
((Graphics2D) g2).draw(body);
((Graphics2D) g2).draw(frontTire);
((Graphics2D) g2).draw(rearTire);
((Graphics2D) g2).draw(frontWindshield);
((Graphics2D) g2).draw(rearWindshield);
((Graphics2D) g2).draw(roofTop);
}
}
Truck
Class: Truck
类别:
package vehiclePackage;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.Ellipse2D;
import java.util.Random;
public class Truck extends Vehicle
{
private int xLeft;
private int yTop;
private int tcount;
public Truck()
{
}
public Truck (int x, int y)
{
super(x, y);
this.xLeft = x;
this.yTop = y;
}
public void draw(Graphics g2)
{
Random rand = new Random();
float red = rand.nextFloat();
float green = rand.nextFloat();
float blue = rand.nextFloat();
Color randomColor = new Color(red, green, blue);
Rectangle body = new Rectangle (xLeft + 22, yTop +10, 60, 20);
Rectangle topCab = new Rectangle(xLeft, yTop + 10, 20, 10);
Rectangle bottomCab = new Rectangle(xLeft, yTop + 20, 20, 10);
Ellipse2D.Double frontTire = new Ellipse2D.Double (xLeft+6, yTop+30, 10, 10);
Ellipse2D.Double midTire = new Ellipse2D.Double (xLeft+25, yTop+30, 10, 10);
Ellipse2D.Double mid2Tire = new Ellipse2D.Double (xLeft+35, yTop+30, 10, 10);
Ellipse2D.Double backTire = new Ellipse2D.Double (xLeft+55, yTop+30, 10, 10);
Ellipse2D.Double back2Tire = new Ellipse2D.Double (xLeft+65, yTop+30, 10, 10);
((Graphics2D) g2).setColor(randomColor);
((Graphics2D) g2).fill(body);
((Graphics2D) g2).fill(bottomCab);
((Graphics2D) g2).fill(frontTire);
((Graphics2D) g2).fill(midTire);
((Graphics2D) g2).fill(mid2Tire);
((Graphics2D) g2).fill(backTire);
((Graphics2D) g2).fill(back2Tire);
((Graphics2D) g2).draw(body);
((Graphics2D) g2).draw(topCab);
((Graphics2D) g2).draw(bottomCab);
((Graphics2D) g2).draw(frontTire);
((Graphics2D) g2).draw(midTire);
((Graphics2D) g2).draw(mid2Tire);
((Graphics2D) g2).draw(backTire);
((Graphics2D) g2).draw(back2Tire);
}
}
VehicleComponent
Class: VehicleComponent
类别:
package vehiclePackage;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Random;
import javax.swing.JComponent;
public class VehicleComponent extends JComponent
{
private int x;
private int y;
private static int ccount = 0;
private static int tcount = 0;
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
Random rand = new Random();
for (int i = 1; i<=10; i ++)
{
int vehic = rand.nextInt(2);
if (vehic == 0)
{
x = rand.nextInt(420);
y = rand.nextInt(545);
Vehicle car = new Car(x, y);
car.draw(g2);
ccount += 1;
}
if (vehic ==1)
{
x = rand.nextInt(420);
y = rand.nextInt(545);
Vehicle truck = new Truck(x, y);
truck.draw(g2);
tcount += 1;
}
}
}
public String toString()
{
return "Trucks: " + tcount + ", Cars: " + ccount;
}
}
VehicleTester
: VehicleTester
:
package vehiclePackage;
import java.awt.BorderLayout;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class VehicleViewer {
public static void main(String[] args)
{
// TODO Auto-generated method stub
JFrame f = new JFrame();
f.setSize(500,600);
f.setTitle("Cars and Trucks");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
VehicleComponent component = new VehicleComponent();
f.add(component);
JLabel runningCount = new JLabel(component.toString());
f.add(runningCount, BorderLayout.SOUTH);
f.setVisible(true);
}
}
Your problem is you're computing the value for the label text before the paintComponent
routine has been called. 您的问题是您在调用paintComponent
例程之前正在计算标签文本的值。 Once it's called, the text is left with the old value. 调用后,文本将保留旧值。
My suggested edit would be to move the figuring of which vehicle to be drawn to the constructor for VehicleComponent
and then when it comes time to draw them, you can look in a pre-populated array to determine what should be drawn, and the counts will already be updated. 我建议的编辑是将要绘制的车辆的图移到VehicleComponent
的构造函数中,然后到绘制它们的时间时,您可以查看一个预先填充的数组以确定应该绘制的内容,然后计数已经更新。
See the updates for VehicleComponent
查看VehicleComponent
的更新
public class VehicleComponent extends JComponent
{
private int x;
private int y;
private int ccount = 0; // these shouldn't be static
private int tcount = 0;
private boolean[] truckOrCar; // simple boolean array (you can change the type as you add more vehicles...)
public VehicleComponent() {
// figure out your car/truck count here
Random rand = new Random();
truckOrCar = new boolean[10];
for (int i = 0; i<10; i ++)
{
int vehic = rand.nextInt(2);
if (vehic == 0)
{
// false for car
truckOrCar[i] = false;
ccount += 1;
}
else {
// true for truck
truckOrCar[i] = true;
tcount += 1;
}
}
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
Random rand = new Random();
// here just look in your list for what to draw
for (int i = 0; i<10; i ++)
{
// false for car
if ( !truckOrCar[i] )
{
x = rand.nextInt(420);
y = rand.nextInt(545);
Vehicle car = new Car(x, y);
car.draw(g2);
ccount += 1;
}
// true for truck
else
{
x = rand.nextInt(420);
y = rand.nextInt(545);
Vehicle truck = new Truck(x, y);
truck.draw(g2);
tcount += 1;
}
}
}
public String toString()
{
return "Trucks: " + tcount + ", Cars: " + ccount;
}
}
See result (though your paint coordinates are a little off...): 查看结果(尽管您的绘制坐标有些偏离...):
What I think you're not understanding is how painting actually works in Swing. 我想您不了解的是绘画在Swing中的实际工作方式。 Painting is destructive, that is, each time your component is painted, it is expected to completely repaint its entire state, from scratch... 绘制是破坏性的,也就是说,每次绘制组件时,都希望从头开始完全重新绘制其整个状态。
Take a look at Performing Custom Painting and Painting in AWT and Swing for more details... 看一下在AWT和Swing中执行自定义绘画和绘画以获取更多详细信息...
So you loops in your paintComponent
method, will, if you're really lucky, only ever paint a single vehicle. 因此,您循环使用paintComponent
方法,如果真的很幸运的话,将只绘制单个车辆。
Instead, you need to maintain the vehicles in some kind of List
or array and simply let paintComponent
paint the lists... 取而代之的是,您需要将车辆保持在某种类型的List
或数组中,并只需用paintComponent
绘制列表即可。
So, we could change VehicleComponent
thus... 因此,我们可以更改VehicleComponent
从而...
public class VehicleComponent extends JComponent {
private List<Car> cars;
private List<Truck> trucks;
private Random rnd = new Random();
public VehicleComponent() {
cars = new ArrayList<>(25);
trucks = new ArrayList<>(25);
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
for (Car car : cars) {
car.draw(g2);
}
for (Truck truck : trucks) {
truck.draw(g2);
}
}
@Override
public String toString() {
return "Trucks: " + trucks.size() + ", Cars: " + cars.size();
}
}
This will now simply paint whatever is in the cars
and trucks
lists when ever the component is repainted... 现在,只要重新喷涂零部件,它就可以简单地喷涂cars
和trucks
清单中的任何东西。
Now, the rest assumes I understand your requirements correctly... 现在,其余的假设我都正确理解了您的要求...
Next, we need some way to add new vehicles to the lists... 接下来,我们需要某种方式将新车添加到列表中...
Not know how you intended to update the component, I wrote this simple method that generates a random number between 0-4
and on 1
it creates a Car
and on 3
it generates a Truck
, you can change this to whatever you like. 不知道您打算如何更新组件,我写了这个简单的方法,它会生成一个0-4
之间的随机数,在1
它会生成Car
,在3
它会生成Truck
,您可以将其更改为任意值。 It checks to see if there is available space in the lists for the new vehicle first before creating them... 它会先检查列表中是否有新车可用的空间,然后再创建它们...
public void addNewVehicle() {
int value = (int) Math.round(Math.random() * 5);
if (value == 1) {
if (cars.size() < 10) {
cars.add(new Car(getSize()));
}
} else if (value == 3) {
if (trucks.size() < 10) {
trucks.add(new Truck(getSize()));
}
} else {
System.out.println("No new toys");
}
repaint();
}
To trigger an update, I use a Swing Timer
, which called the addNewVehicle
method every second... 为了触发更新,我使用了Swing Timer
,它addNewVehicle
调用一次addNewVehicle
方法...
Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
component.addNewVehicle();
runningCount.setText(component.toString());
}
});
timer.start();
Adding in the randomised nature of the addNewVehicle
method, this means you won't see a vehicle added every second. 加上addNewVehicle
方法的addNewVehicle
,这意味着您不会看到每秒增加一辆载具。 This also updates the runningCount
label at the same time, keeping it in sync... 这还将同时更新runningCount
标签,使其保持同步...
Now, given the nature of painting process, I changed the way your Truck
and Car
paint, instead of randomizing the color each time they are drawn, I randomized the color when each instance is created instead 现在,考虑到绘画过程的本质,我更改了“ Truck
和“ Car
油漆的方式,而不是在每次绘制时随机化颜色,而是在创建每个实例时随机化颜色
public class Car extends Vehicle {
private int xLeft;
private int yTop;
private Color color;
public Car(Dimension size) {
xLeft = (int) Math.round((Math.random() * size.width - 60));
yTop = (int) Math.round((Math.random() * size.height - 10));
Random rand = new Random();
float red = rand.nextFloat();
float green = rand.nextFloat();
float blue = rand.nextFloat();
color = new Color(red, green, blue);
}
@Override
public void draw(Graphics g2) {
Rectangle body = new Rectangle(xLeft, yTop + 10, 60, 10);
Ellipse2D.Double frontTire = new Ellipse2D.Double(xLeft + 10, yTop + 20, 10, 10);
Ellipse2D.Double rearTire = new Ellipse2D.Double(xLeft + 40, yTop + 20, 10, 10);
Point2D.Double r1 = new Point2D.Double(xLeft + 10, yTop + 10);
Point2D.Double r2 = new Point2D.Double(xLeft + 20, yTop);
Point2D.Double r3 = new Point2D.Double(xLeft + 40, yTop);
Point2D.Double r4 = new Point2D.Double(xLeft + 50, yTop + 10);
Line2D.Double frontWindshield = new Line2D.Double(r1, r2);
Line2D.Double roofTop = new Line2D.Double(r2, r3);
Line2D.Double rearWindshield = new Line2D.Double(r3, r4);
((Graphics2D) g2).setColor(color);
((Graphics2D) g2).fill(body);
((Graphics2D) g2).fill(frontTire);
((Graphics2D) g2).fill(rearTire);
((Graphics2D) g2).draw(body);
((Graphics2D) g2).draw(frontTire);
((Graphics2D) g2).draw(rearTire);
((Graphics2D) g2).draw(frontWindshield);
((Graphics2D) g2).draw(rearWindshield);
((Graphics2D) g2).draw(roofTop);
}
}
public class Truck extends Vehicle {
private int xLeft;
private int yTop;
private Color color;
public Truck(Dimension size) {
xLeft = (int) Math.round((Math.random() * size.width - 60));
yTop = (int) Math.round((Math.random() * size.height - 20));
Random rand = new Random();
float red = rand.nextFloat();
float green = rand.nextFloat();
float blue = rand.nextFloat();
color = new Color(red, green, blue);
}
@Override
public void draw(Graphics g2) {
Rectangle body = new Rectangle(xLeft + 22, yTop + 10, 60, 20);
Rectangle topCab = new Rectangle(xLeft, yTop + 10, 20, 10);
Rectangle bottomCab = new Rectangle(xLeft, yTop + 20, 20, 10);
Ellipse2D.Double frontTire = new Ellipse2D.Double(xLeft + 6, yTop + 30, 10, 10);
Ellipse2D.Double midTire = new Ellipse2D.Double(xLeft + 25, yTop + 30, 10, 10);
Ellipse2D.Double mid2Tire = new Ellipse2D.Double(xLeft + 35, yTop + 30, 10, 10);
Ellipse2D.Double backTire = new Ellipse2D.Double(xLeft + 55, yTop + 30, 10, 10);
Ellipse2D.Double back2Tire = new Ellipse2D.Double(xLeft + 65, yTop + 30, 10, 10);
((Graphics2D) g2).setColor(color);
((Graphics2D) g2).fill(body);
((Graphics2D) g2).fill(bottomCab);
((Graphics2D) g2).fill(frontTire);
((Graphics2D) g2).fill(midTire);
((Graphics2D) g2).fill(mid2Tire);
((Graphics2D) g2).fill(backTire);
((Graphics2D) g2).fill(back2Tire);
((Graphics2D) g2).draw(body);
((Graphics2D) g2).draw(topCab);
((Graphics2D) g2).draw(bottomCab);
((Graphics2D) g2).draw(frontTire);
((Graphics2D) g2).draw(midTire);
((Graphics2D) g2).draw(mid2Tire);
((Graphics2D) g2).draw(backTire);
((Graphics2D) g2).draw(back2Tire);
}
}
Now, cause that could be some effort to piece back together, this is the code I used to test it... 现在,可能需要花费一些精力才能重新组合起来,这是我用来测试的代码...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final VehicleComponent component = new VehicleComponent();
frame.add(component);
final JLabel runningCount = new JLabel(component.toString());
frame.add(runningCount, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
component.addNewVehicle();
runningCount.setText(component.toString());
}
});
timer.start();
}
});
}
public abstract class Vehicle {
public abstract void draw(Graphics g2);
}
public class Car extends Vehicle {
private int xLeft;
private int yTop;
private Color color;
public Car(Dimension size) {
xLeft = (int) Math.round((Math.random() * size.width - 60));
yTop = (int) Math.round((Math.random() * size.height - 10));
Random rand = new Random();
float red = rand.nextFloat();
float green = rand.nextFloat();
float blue = rand.nextFloat();
color = new Color(red, green, blue);
}
@Override
public void draw(Graphics g2) {
Rectangle body = new Rectangle(xLeft, yTop + 10, 60, 10);
Ellipse2D.Double frontTire = new Ellipse2D.Double(xLeft + 10, yTop + 20, 10, 10);
Ellipse2D.Double rearTire = new Ellipse2D.Double(xLeft + 40, yTop + 20, 10, 10);
Point2D.Double r1 = new Point2D.Double(xLeft + 10, yTop + 10);
Point2D.Double r2 = new Point2D.Double(xLeft + 20, yTop);
Point2D.Double r3 = new Point2D.Double(xLeft + 40, yTop);
Point2D.Double r4 = new Point2D.Double(xLeft + 50, yTop + 10);
Line2D.Double frontWindshield = new Line2D.Double(r1, r2);
Line2D.Double roofTop = new Line2D.Double(r2, r3);
Line2D.Double rearWindshield = new Line2D.Double(r3, r4);
((Graphics2D) g2).setColor(color);
((Graphics2D) g2).fill(body);
((Graphics2D) g2).fill(frontTire);
((Graphics2D) g2).fill(rearTire);
((Graphics2D) g2).draw(body);
((Graphics2D) g2).draw(frontTire);
((Graphics2D) g2).draw(rearTire);
((Graphics2D) g2).draw(frontWindshield);
((Graphics2D) g2).draw(rearWindshield);
((Graphics2D) g2).draw(roofTop);
}
}
public class Truck extends Vehicle {
private int xLeft;
private int yTop;
private Color color;
public Truck(Dimension size) {
xLeft = (int) Math.round((Math.random() * size.width - 60));
yTop = (int) Math.round((Math.random() * size.height - 20));
Random rand = new Random();
float red = rand.nextFloat();
float green = rand.nextFloat();
float blue = rand.nextFloat();
color = new Color(red, green, blue);
}
@Override
public void draw(Graphics g2) {
Rectangle body = new Rectangle(xLeft + 22, yTop + 10, 60, 20);
Rectangle topCab = new Rectangle(xLeft, yTop + 10, 20, 10);
Rectangle bottomCab = new Rectangle(xLeft, yTop + 20, 20, 10);
Ellipse2D.Double frontTire = new Ellipse2D.Double(xLeft + 6, yTop + 30, 10, 10);
Ellipse2D.Double midTire = new Ellipse2D.Double(xLeft + 25, yTop + 30, 10, 10);
Ellipse2D.Double mid2Tire = new Ellipse2D.Double(xLeft + 35, yTop + 30, 10, 10);
Ellipse2D.Double backTire = new Ellipse2D.Double(xLeft + 55, yTop + 30, 10, 10);
Ellipse2D.Double back2Tire = new Ellipse2D.Double(xLeft + 65, yTop + 30, 10, 10);
((Graphics2D) g2).setColor(color);
((Graphics2D) g2).fill(body);
((Graphics2D) g2).fill(bottomCab);
((Graphics2D) g2).fill(frontTire);
((Graphics2D) g2).fill(midTire);
((Graphics2D) g2).fill(mid2Tire);
((Graphics2D) g2).fill(backTire);
((Graphics2D) g2).fill(back2Tire);
((Graphics2D) g2).draw(body);
((Graphics2D) g2).draw(topCab);
((Graphics2D) g2).draw(bottomCab);
((Graphics2D) g2).draw(frontTire);
((Graphics2D) g2).draw(midTire);
((Graphics2D) g2).draw(mid2Tire);
((Graphics2D) g2).draw(backTire);
((Graphics2D) g2).draw(back2Tire);
}
}
public class VehicleComponent extends JComponent {
private int x;
private int y;
private List<Car> cars;
private List<Truck> trucks;
private Random rnd = new Random();
public VehicleComponent() {
cars = new ArrayList<>(25);
trucks = new ArrayList<>(25);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
for (Car car : cars) {
car.draw(g2);
}
for (Truck truck : trucks) {
truck.draw(g2);
}
}
public void addNewVehicle() {
int value = (int) Math.round(Math.random() * 5);
if (value == 1) {
if (cars.size() < 10) {
cars.add(new Car(getSize()));
}
} else if (value == 3) {
if (trucks.size() < 10) {
trucks.add(new Truck(getSize()));
}
} else {
System.out.println("No new toys");
}
repaint();
}
@Override
public String toString() {
return "Trucks: " + trucks.size() + ", Cars: " + cars.size();
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.