我查看了一些类似于我的其他问题,但是当我尝试修复它们时,它们似乎没有任何帮助,我将如何解决这个问题,因为它是阻止我的程序打印矩形的唯一因素,这是至关重要的。
以下是整个程序的代码,因为我不确定问题出在哪里,只有问题所在。评论的内容我目前没有使用,但是我将它保留在那里,以防我以后找到它的用途。非常感谢
目前,我的程序没有绘制任何类型的矩形,因为重绘不会调用paintcomponent。我的问题基本上是询问为什么在我开始时没有打印任何内容。
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.logging.Logger;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/**
* Write a description of class Game here.
*
* @author Adam Steele
* @version 1.0.0
*/
public class Game extends JPanel implements MouseListener
{
// logger
private static final Logger LOGGER = Logger.getLogger(Game.class.getName());
// variables
private boolean isGolden; // Class wide boolean for whether rectangle is golden
private int score; // Stores the score
private int noOfAttempts; // stores number of rectangles that are created
private int goldTimer; // attempts before fail & new rectangle is created
// graphics
private Rectangle box;
private JFrame frame;
private JPanel panel;
// testing
private ArrayList<Rect> rects = new ArrayList<Rect>();
/**
* Constructor for objects of class Game
*/
public Game()
{
setup();
}
public void setup()
{
LOGGER.info("setup has been called");
// initalise frame
frame = new JFrame();
final int FRAME_WIDTH = 800;
final int FRAME_HEIGHT = 600;
// set frame attributes
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setTitle("Gold Picker");
// initalise panel
panel = new JPanel();
panel.addMouseListener(this);
// add things to panel - ie. score, time limit, etc.
// panel.add();
JLabel amLabel = new JLabel("I am a GUI label.");
panel.add(amLabel);
JButton button = new JButton("Button");
button.setBackground(Color.YELLOW);
button.setForeground(Color.GREEN);
panel.add(button);
// add panel to frame
frame.add(panel);
// Make frame visible
showFrame();
LOGGER.info("Game window has been created");
// (re)set variables
score = 0;
noOfAttempts = 0;
goldTimer = 30;
// this is to check variable initalisation
LOGGER.info("Variables have been initalised at: score = " + score + ", noOfAttempts = " + noOfAttempts + ", goldTimer = " + goldTimer);
// start game
decideGolden();
}
public void showFrame()
{
frame.setVisible(true);
}
/**
* A method that decides if the rectangle will be golden based on a random chance
*/
public void decideGolden()
{
double goldProportion = Math.random() * 1;
double goldChance = Math.random() * 1;
//System.out.println(goldChance + " " + goldProportion);
if(goldChance <= goldProportion) {
isGolden = true;
} else {
isGolden = false;
}
LOGGER.info("isGolden has been set to " + isGolden);
timedRect();
}
/**
* Method for generating rectangled on timed intervals
*/
public void timedRect()
{
/*
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run()
{
}
}, 20000, 20000 );
/*
if(isGolden) {
repaint();
} else {
createNormalRectangle();
}
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
}
},
20000); */
LOGGER.info("timedRect has been called");
for(int i = 0; i < goldTimer; i++) {
try {
LOGGER.info("try has been reached");
//repaint();
drawRectangle();
Thread.sleep(20000); // wait 20 seconds..
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
LOGGER.info("paintComponent has been called with " + g);
/*
int x = 400;
int y = 300;
// Using Math.random() or .nextInt() we could make random gold rects
int width = 100;
int height = 100;
LOGGER.info("x = " + x + ", y = " + y + ", width = " + width + ", height = " + height);
if(isGolden) {
//g.drawRect(x, y, width, height);
g.setColor(Color.BLACK);
g.fillRect(x, y, 100, 100); // g.fillRect(x, y, size, size);
} else {
//g.drawRect(x, y, width, height);
g.setColor(Color.BLACK);
g.fillRect(x, y, 100, 100);
}
*/
Graphics2D g2d = (Graphics2D) g;
for(Rect rectangle : rects) { // for each Rect object in rect ArrayList ..
rectangle.paint(g2d);
}
}
/**
*
*/
public void drawRectangle()
{
int x = (int) (Math.random() * getWidth());
int y = (int) (Math.random() * getHeight());
int width = (int) (Math.random() * (getWidth() / 4));
int height = (int) (Math.random() * (getHeight() / 4));
// LOGGER.info("x = " + x + ", y = " + y + ", width = " + width + ", height = " + height);
if (x + width > getWidth()) {
x = getWidth() - width;
}
if (y + height > getHeight()) {
y = getHeight() - height;
}
Color color = new Color(
(int) (Math.random() * 255),
(int) (Math.random() * 255),
(int) (Math.random() * 255));
rects.add(new Rect(x, y, width, height, color));
repaint();
// LOGGER.info("repaint has been called, check if paintComponent has been called..");
}
/**
* these methods are needed to override the MouseListener
* ..and hence needed to implement the MouseListener
* ..which will probably only be used for testing
* ..actionlistener maybe more appropriate
*/
@Override
public void mouseClicked(MouseEvent e) {
LOGGER.info("Mouse has been clicked");
drawRectangle();
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
}
Rect类,以防需要
Rect class
import java.awt.*;
/**
* Deaals with misc properties of rect
* Inherits the Rectangle class from java.awt.Rectangle
public class Rect extends Rectangle
{
private Color color;
/**
* Constructor for objects of class Rect
*/
public Rect(int x, int y, int width, int height, Color color)
{
super(x, y, width, height);
this.color = color;
}
public void paint(Graphics2D g2d)
{
g2d.setColor(color);
g2d.fill(this);
}
}
答案 0 :(得分:1)
基本上,您实际上从未将Game
添加到可以显示它的任何内容上,因此它永远不会被绘制。
在绘制组件之前,必须将其添加到在屏幕上实现的容器中。
您遇到的问题之一是您的Game
课程承担了很多责任,应该专注于展示和管理游戏状态,而不是创建基本用户界面。
您将遇到的另一个问题是timedRect
方法会阻止EDT,阻止任何内容被绘制
这是一个基本的&#34;例如(我没有对其进行测试,因为我没有Rect
课程),但从概念上讲,它应该让您更接近目标。
实际上,我有一个单独的&#34;主要&#34;启动应用程序的类,设置初始状态,创建UI并使球滚动。
import java.awt.Color;
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.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import org.w3c.dom.css.Rect;
public class Game extends JPanel implements MouseListener {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
LOGGER.info("setup has been called");
// initalise frame
JFrame frame = new JFrame();
final int FRAME_WIDTH = 800;
final int FRAME_HEIGHT = 600;
// set frame attributes
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setTitle("Gold Picker");
// initalise panel
JPanel panel = new Game();
// add things to panel - ie. score, time limit, etc.
// panel.add();
JLabel amLabel = new JLabel("I am a GUI label.");
panel.add(amLabel);
JButton button = new JButton("Button");
button.setBackground(Color.YELLOW);
button.setForeground(Color.GREEN);
panel.add(button);
// add panel to frame
frame.add(panel);
frame.setVisible(true);
LOGGER.info("Game window has been created");
}
});
}
// logger
private static final Logger LOGGER = Logger.getLogger(Game.class.getName());
// variables
private boolean isGolden; // Class wide boolean for whether rectangle is golden
private int score; // Stores the score
private int noOfAttempts; // stores number of rectangles that are created
private int goldTimer; // attempts before fail & new rectangle is created
private int gameLoops = 0;
// graphics
private Rectangle box;
// testing
private ArrayList<Rect> rects = new ArrayList<Rect>();
/**
* Constructor for objects of class Game
*/
public Game() {
addMouseListener(this);
// (re)set variables
score = 0;
noOfAttempts = 0;
goldTimer = 30;
// this is to check variable initalisation
LOGGER.info("Variables have been initalised at: score = " + score + ", noOfAttempts = " + noOfAttempts + ", goldTimer = " + goldTimer);
decideGolden();
}
/**
* A method that decides if the rectangle will be golden based on a random
* chance
*/
public void decideGolden() {
double goldProportion = Math.random() * 1;
double goldChance = Math.random() * 1;
//System.out.println(goldChance + " " + goldProportion);
if (goldChance <= goldProportion) {
isGolden = true;
} else {
isGolden = false;
}
LOGGER.info("isGolden has been set to " + isGolden);
timedRect();
}
/**
* Method for generating rectangled on timed intervals
*/
public void timedRect() {
Timer timer = new Timer(2000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (gameLoops < goldTimer) {
LOGGER.info("try has been reached");
//repaint();
drawRectangle();
gameLoops++;
} else {
((Timer) (e.getSource())).stop();
}
}
});
timer.start();
LOGGER.info("timedRect has been called");
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
LOGGER.info("paintComponent has been called with " + g);
Graphics2D g2d = (Graphics2D) g;
for (Rect rectangle : rects) { // for each Rect object in rect ArrayList ..
rectangle.paint(g2d);
}
}
/**
*
*/
public void drawRectangle() {
int x = (int) (Math.random() * getWidth());
int y = (int) (Math.random() * getHeight());
int width = (int) (Math.random() * (getWidth() / 4));
int height = (int) (Math.random() * (getHeight() / 4));
// LOGGER.info("x = " + x + ", y = " + y + ", width = " + width + ", height = " + height);
if (x + width > getWidth()) {
x = getWidth() - width;
}
if (y + height > getHeight()) {
y = getHeight() - height;
}
Color color = new Color(
(int) (Math.random() * 255),
(int) (Math.random() * 255),
(int) (Math.random() * 255));
rects.add(new Rect(x, y, width, height, color));
repaint();
LOGGER.info("repaint has been called, check if paintComponent has been called..");
}
/**
* these methods are needed to override the MouseListener ..and hence needed
* to implement the MouseListener ..which will probably only be used for
* testing ..actionlistener maybe more appropriate
*/
@Override
public void mouseClicked(MouseEvent e) {
LOGGER.info("Mouse has been clicked");
drawRectangle();
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public class Rect extends Rectangle {
private Color color;
/**
* Constructor for objects of class Rect
*/
public Rect(int x, int y, int width, int height, Color color) {
super(x, y, width, height);
this.color = color;
}
public void paint(Graphics2D g2d) {
g2d.setColor(color);
g2d.fill(this);
}
}
}
答案 1 :(得分:0)
为什么在拥有JPanel实例时扩展JPanel?扩展类时,将继承其所有功能。 不要使用你的实例“panel.add”,而是摆脱你的JPanel实例并使用this.add。
这导致我的下一个声明: 你的类应该扩展JComponent,你没有覆盖paintcomponent,因为JPanel没有要覆盖的paintcomponent()方法。
了解如何正确实现JComponent和JFrame以及它们如何结合在一起。通常将所有绘图添加到JComponent,然后说frame.add(component),其中component是JComponent类型。
尝试以这种方式重新实现您的代码并分离您的课程,现在您不必遵循这种确切的格式,但是根据您发布的内容,我认为您已经迷失了。
实现一个扩展JComponent的类,这个类可能有一个“矩形”对象的arraylist。
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// initialize your rectangle objects here
for(Rectangles rects: whateveryourarraylistvariable) {
rects.draw(g2);
}
}