无法使程序打印多于一个正方形。
我现在的代码
import java.awt.*;
import javax.swing.*;
public class MyApplication extends JFrame {
private static final Dimension WindowSize = new Dimension(600, 600);
private int xCord=9, yCord=32, width=80, height=80;
public MyApplication() {
//Create and set up the window
this.setTitle("Squares");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Display the window centered on the screen
Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
int x = screensize.width / 2 - WindowSize.width / 2;
int y = screensize.height / 2 - WindowSize.height / 2;
setBounds(x, y, WindowSize.width, WindowSize.height);
setVisible(true);
}
public static void main(String args[]) {
MyApplication window = new MyApplication();
}
public void paint(Graphics g) {
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
g.setColor(Color.getHSBColor(red, green, blue));
g.fillRect(xCord, yCord, width, height);
while((yCord+height)<600){
if((xCord+width)>600){
xCord=9;
yCord+=80;
}
else xCord+=80;
repaint();
}
}
}
我正在尝试用不同颜色的正方形填充600x600的窗口,一旦行已满,这些颜色将转到新行。
答案 0 :(得分:3)
首先,不要。
请勿覆盖paint
之类的顶级容器中的JFrame
。
JFrame
是一个复合组件,这意味着它们是其表面和用户之间的许多层,并且由于绘画系统的工作方式,可以独立于框架进行绘画,从而产生结果很奇怪。
顶级容器没有双重缓冲,这意味着您的更新将闪烁。
除非您完全确定自己知道自己在做什么,否则请调用paint方法的超级方法。
首先查看Performing Custom Painting和Painting in AWT and Swing,以了解有关绘画在Swing中的工作方式以及如何使用它的更多详细信息。
这个...
Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
int x = screensize.width / 2 - WindowSize.width / 2;
int y = screensize.height / 2 - WindowSize.height / 2;
setBounds(x, y, WindowSize.width, WindowSize.height);
在许多层面上都是个坏主意。
Toolkit#getScreenSize
没有考虑其他UI元素的大小,这会减少屏幕上可用的可视区域,例如某些OS上的任务栏/停靠栏或菜单栏。
在基于窗口的类上使用setBounds(x, y, WindowSize.width, WindowSize.height);
也是一个坏主意,因为可用的可见区域是窗口大小减去窗口装饰的大小,这意味着实际可见的区域要比您指定的要小,因为直接在框架上绘画,则有在框架装饰下绘画的风险。
您可以查看How can I set in the midst?了解更多详细信息
您现在应该进行的涂装一件事是,涂装具有破坏性,也就是说,每次发生涂装周期时,都希望您完全重涂组件的当前状态。
当前,这个...
public void paint(Graphics g) {
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
g.setColor(Color.getHSBColor(red, green, blue));
g.fillRect(xCord, yCord, width, height);
while ((yCord + height) < 600) {
if ((xCord + width) > 600) {
xCord = 9;
yCord += 80;
} else {
xCord += 80;
}
repaint();
}
}
将仅根据xCord
方法退出后yCord
和paint
的最后一个值绘制一个矩形。
Swing使用被动渲染引擎,这意味着系统将确定要绘画的内容以及何时不受控制。您可以通过使用repaint
向系统发出“请求”,但这取决于系统来决定何时以及将要绘画什么,这意味着可以将多个请求优化到单个绘画遍。 / p>
此外,绘画只不过要绘画当前状态而已。应该避免直接或间接更改状态,尤其是如果该更改触发了新的绘制过程,因为这会突然将程序的性能降低到0,从而使其失效。
好吧,改变一切...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MyApplication {
public static void main(String[] args) {
new MyApplication();
}
public MyApplication() {
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);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
private static final Dimension DESIRED_SIZE = new Dimension(600, 600);
private int width = 80, height = 80;
public TestPane() {
}
@Override
public Dimension getPreferredSize() {
return DESIRED_SIZE;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int xCord = 0, yCord = 0;
while ((yCord) < getHeight()) {
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
g2d.setColor(Color.getHSBColor(red, green, blue));
g2d.fillRect(xCord, yCord, width, height);
if ((xCord + width) > getWidth()) {
xCord = 0;
yCord += 80;
} else {
xCord += 80;
}
}
g2d.dispose();
}
}
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
这将创建一个Jframe
的实例,您真的不想从JFrame
进行扩展,也没有在该类中添加任何新功能
frame.pack()
将窗口包装在内容周围,以确保框架始终比所需的内容尺寸大(按框架装饰的数量)
frame.setLocationRelativeTo(null);
将以系统独立的方式使窗口居中。
下一步...
private static final Dimension DESIRED_SIZE = new Dimension(600, 600);
private int width = 80, height = 80;
public TestPane() {
}
@Override
public Dimension getPreferredSize() {
return DESIRED_SIZE;
}
我已经使用DESIRED_SIZE
向父容器布局管理器提供了大小调整提示。
最后...
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int xCord = 0, yCord = 0;
while ((yCord) < getHeight()) {
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
g2d.setColor(Color.getHSBColor(red, green, blue));
g2d.fillRect(xCord, yCord, width, height);
if ((xCord + width) > getWidth()) {
xCord = 0;
yCord += 80;
} else {
xCord += 80;
}
}
g2d.dispose();
}
请注意,在这里,我已经将xCord
和yCord
的位置更改为零,我不再需要猜测框架的装饰。除了创建局部变量之外,以便在再次调用该方法时,这些值都将重置为零。
您没有“必须”将Graphics
引用强制转换为Graphics2D
,但是Graphics2D
是更强大的API。我也想复制它的状态,但这就是我,您的代码很简单,因此不太可能对组件后可能绘制的任何其他内容产生不利影响。
还要注意,我使用了getWidth
和getHeight
而不是“幻数”,这意味着您可以调整窗口的大小,并且绘画会适应。
答案 1 :(得分:0)
您可以尝试将整个绘制机制放在循环中,以在一次调用中完成。因此,您将不需要在paint方法本身内部调用repaint:
public void paint(Graphics g) {
while((yCord+height)<600){
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
g.setColor(Color.getHSBColor(red, green, blue));
g.fillRect(xCord, yCord, width, height);
if((xCord+width)>600){
xCord=9;
yCord+=80;
}
else xCord+=80;
}
}