import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class Panel2 extends Frame {
private final int margin_left = 10;
private final int margin_top = 10;
private final int block_size = 20;
private final int board_dim = 15;
public Panel2() {
setTitle("五子棋游戏");
setVisible(true);
setLayout(null);
setBounds(0, 0, 600, 600);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setBackground(Color.YELLOW);
}
public void paint(Graphics g) {
int i;
for (i = 0; i < board_dim; i++) {
// 横线 15*15的棋盘
int x1 = margin_left;
int y1 = margin_top + i * block_size;
int x2 = margin_left + block_size*(board_dim-1);
int y2 = y1;
g.drawLine(x1, y1, x2, y2);
}
for (i = 0; i < board_dim; i++) {
// 竖线 15*15的棋盘
int x1 = margin_left + i * block_size;
int y1 = margin_top;
int x2 = x1;
int y2 = margin_top + block_size*(board_dim-1);
g.drawLine(x1, y1, x2, y2);
}
int radius = 3;
int x1 = margin_left + board_dim/2*block_size;
int y1 = margin_top + board_dim/2*block_size;
g.fillOval(x1 - radius, y1 - radius, radius*2, radius*2);// 画点
int shift = (board_dim/4+1)*block_size;
g.fillOval(x1- shift - radius, y1 -shift - radius, radius*2, radius*2);
g.fillOval(x1-shift - radius, y1 +shift - radius, radius*2, radius*2);
g.fillOval(x1+shift - radius, y1 -shift - radius, radius*2, radius*2);
g.fillOval(x1+shift - radius, y1 +shift - radius, radius*2, radius*2);
}
public static void main(String[] args) {
Panel2 p = new Panel2();
}
}
请大家帮忙分析一下,啥原因呢
8 个解决方案
#1
setBounds(0, 0, 600, 600); 这个组建的600*600是整体大小,包含了边框
private final int margin_top = 50; 设置大一些就可以了
private final int margin_top = 50; 设置大一些就可以了
#2
这是正确的情况
这是有问题的情况
同样的代码,执行的结果不一样,可能是一些渲染线程的问题,但我不知道如何去找
这是有问题的情况
同样的代码,执行的结果不一样,可能是一些渲染线程的问题,但我不知道如何去找
#3
谢谢你的回答,然而,
并不是这样的问题,横线从来没有越过边界。
#4
帮你改造了下
先是Frame
下面是面板Panel1
先是Frame
package test;
import java.awt.Color;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
public class WuziFrame extends JFrame {
private static final long serialVersionUID = 1L;
public WuziFrame() {
setTitle("五子棋游戏");
setLayout(null);
setBounds(0, 0, 600, 600);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setBackground(Color.YELLOW);
Panel1 panel1 = new Panel1();
this.setContentPane(panel1);
}
public static void main(String[] args) {
WuziFrame p = new WuziFrame();
p.setVisible(true);
}
}
下面是面板Panel1
package test;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Panel1 extends JPanel {
private static final long serialVersionUID = 1L;
private final int margin_left = 10;
private final int margin_top = 10;
private final int block_size = 20;
private final int board_dim = 15;
public void paint(Graphics g) {
int i;
for (i = 0; i < board_dim; i++) {
// 横线 15*15的棋盘
int x1 = margin_left;
int y1 = margin_top + i * block_size;
int x2 = margin_left + block_size*(board_dim-1);
int y2 = y1;
g.drawLine(x1, y1, x2, y2);
System.out.println(x1+","+y1);
}
for (i = 0; i < board_dim; i++) {
// 竖线 15*15的棋盘
int x1 = margin_left + i * block_size;
int y1 = margin_top;
int x2 = x1;
int y2 = margin_top + block_size*(board_dim-1);
g.drawLine(x1, y1, x2, y2);
}
int radius = 3;
int x1 = margin_left + board_dim/2*block_size;
int y1 = margin_top + board_dim/2*block_size;
g.fillOval(x1 - radius, y1 - radius, radius*2, radius*2);// 画点
int shift = (board_dim/4+1)*block_size;
g.fillOval(x1- shift - radius, y1 -shift - radius, radius*2, radius*2);
g.fillOval(x1-shift - radius, y1 +shift - radius, radius*2, radius*2);
g.fillOval(x1+shift - radius, y1 -shift - radius, radius*2, radius*2);
g.fillOval(x1+shift - radius, y1 +shift - radius, radius*2, radius*2);
}
}
#5
另外,awt里的Frame的边界是从标题栏算起,而swing中的JFrame是从内容面板算,这就是导致你画出来的表格显示不完整的原因,你用awt的Frame的话,就要把top上的距离设大一点
#6
这个问题的解决方案是在setVisible方法后面(只有在此方法之后调用才有效)添加一些代码(需要把这些变量的final修饰符去掉):
原理如楼上所讲,paint中的graphics绘图原点在窗体的左上角(也算标题栏,在关闭按钮的左上边那个角)
其度量方法就是获得窗体的Insets,表示上下左右边界的宽度。
调用完以上方法后repaint()重绘窗体,使修改生效。
最好的办法是不要直接在frame中绘图,而是extends某个componet,如panel等,重写它们的paint和update方法。它们的左上角一定会在窗体的里面的,而且易于通过布局控制大小和位置。
另,现在不再推荐使用Frame,而是使用JFrame。
setVisible(true);
Insets i = getInsets();
margin_left += i.left;
margin_top += i.top;
repaint();
原理如楼上所讲,paint中的graphics绘图原点在窗体的左上角(也算标题栏,在关闭按钮的左上边那个角)
其度量方法就是获得窗体的Insets,表示上下左右边界的宽度。
调用完以上方法后repaint()重绘窗体,使修改生效。
最好的办法是不要直接在frame中绘图,而是extends某个componet,如panel等,重写它们的paint和update方法。它们的左上角一定会在窗体的里面的,而且易于通过布局控制大小和位置。
另,现在不再推荐使用Frame,而是使用JFrame。
#7
说实话,这个swing属于native的方案,将来趋势是html5建议使用html5来做界面啦。。方便有跨平台。
#8
JFrame只是一个外框,里面有一个内容面板,你的JPanel添加到这个内容面板上,所以绘制的时候所有的内容不是画在JFrame上,而是画在JPanel上,你要用JPanel的大小作为边界条件。
参考四楼的代码,虽然我没仔细看,但是大概是那个意思
参考四楼的代码,虽然我没仔细看,但是大概是那个意思
#1
setBounds(0, 0, 600, 600); 这个组建的600*600是整体大小,包含了边框
private final int margin_top = 50; 设置大一些就可以了
private final int margin_top = 50; 设置大一些就可以了
#2
这是正确的情况
这是有问题的情况
同样的代码,执行的结果不一样,可能是一些渲染线程的问题,但我不知道如何去找
这是有问题的情况
同样的代码,执行的结果不一样,可能是一些渲染线程的问题,但我不知道如何去找
#3
谢谢你的回答,然而,
并不是这样的问题,横线从来没有越过边界。
#4
帮你改造了下
先是Frame
下面是面板Panel1
先是Frame
package test;
import java.awt.Color;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
public class WuziFrame extends JFrame {
private static final long serialVersionUID = 1L;
public WuziFrame() {
setTitle("五子棋游戏");
setLayout(null);
setBounds(0, 0, 600, 600);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setBackground(Color.YELLOW);
Panel1 panel1 = new Panel1();
this.setContentPane(panel1);
}
public static void main(String[] args) {
WuziFrame p = new WuziFrame();
p.setVisible(true);
}
}
下面是面板Panel1
package test;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Panel1 extends JPanel {
private static final long serialVersionUID = 1L;
private final int margin_left = 10;
private final int margin_top = 10;
private final int block_size = 20;
private final int board_dim = 15;
public void paint(Graphics g) {
int i;
for (i = 0; i < board_dim; i++) {
// 横线 15*15的棋盘
int x1 = margin_left;
int y1 = margin_top + i * block_size;
int x2 = margin_left + block_size*(board_dim-1);
int y2 = y1;
g.drawLine(x1, y1, x2, y2);
System.out.println(x1+","+y1);
}
for (i = 0; i < board_dim; i++) {
// 竖线 15*15的棋盘
int x1 = margin_left + i * block_size;
int y1 = margin_top;
int x2 = x1;
int y2 = margin_top + block_size*(board_dim-1);
g.drawLine(x1, y1, x2, y2);
}
int radius = 3;
int x1 = margin_left + board_dim/2*block_size;
int y1 = margin_top + board_dim/2*block_size;
g.fillOval(x1 - radius, y1 - radius, radius*2, radius*2);// 画点
int shift = (board_dim/4+1)*block_size;
g.fillOval(x1- shift - radius, y1 -shift - radius, radius*2, radius*2);
g.fillOval(x1-shift - radius, y1 +shift - radius, radius*2, radius*2);
g.fillOval(x1+shift - radius, y1 -shift - radius, radius*2, radius*2);
g.fillOval(x1+shift - radius, y1 +shift - radius, radius*2, radius*2);
}
}
#5
另外,awt里的Frame的边界是从标题栏算起,而swing中的JFrame是从内容面板算,这就是导致你画出来的表格显示不完整的原因,你用awt的Frame的话,就要把top上的距离设大一点
#6
这个问题的解决方案是在setVisible方法后面(只有在此方法之后调用才有效)添加一些代码(需要把这些变量的final修饰符去掉):
原理如楼上所讲,paint中的graphics绘图原点在窗体的左上角(也算标题栏,在关闭按钮的左上边那个角)
其度量方法就是获得窗体的Insets,表示上下左右边界的宽度。
调用完以上方法后repaint()重绘窗体,使修改生效。
最好的办法是不要直接在frame中绘图,而是extends某个componet,如panel等,重写它们的paint和update方法。它们的左上角一定会在窗体的里面的,而且易于通过布局控制大小和位置。
另,现在不再推荐使用Frame,而是使用JFrame。
setVisible(true);
Insets i = getInsets();
margin_left += i.left;
margin_top += i.top;
repaint();
原理如楼上所讲,paint中的graphics绘图原点在窗体的左上角(也算标题栏,在关闭按钮的左上边那个角)
其度量方法就是获得窗体的Insets,表示上下左右边界的宽度。
调用完以上方法后repaint()重绘窗体,使修改生效。
最好的办法是不要直接在frame中绘图,而是extends某个componet,如panel等,重写它们的paint和update方法。它们的左上角一定会在窗体的里面的,而且易于通过布局控制大小和位置。
另,现在不再推荐使用Frame,而是使用JFrame。
#7
说实话,这个swing属于native的方案,将来趋势是html5建议使用html5来做界面啦。。方便有跨平台。
#8
JFrame只是一个外框,里面有一个内容面板,你的JPanel添加到这个内容面板上,所以绘制的时候所有的内容不是画在JFrame上,而是画在JPanel上,你要用JPanel的大小作为边界条件。
参考四楼的代码,虽然我没仔细看,但是大概是那个意思
参考四楼的代码,虽然我没仔细看,但是大概是那个意思