Java Swing Frame 有点不对劲?
Java Swing Frame is a tad off?
我有一个简单的动画代码,可以创建一个仪表类型的矩形效果。我想创建它以使其完全填满面板。我离得太近了,但它延伸到了底部的框架之外。我错过了什么?
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("Pong");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(1,2));
frame.setSize(500, 500);
//MouseTest test = new MouseTest();
Test test2 = new Test(frame.getWidth(), frame.getHeight(), frame.getHeight(), 50);
//frame.add(test);
frame.add(test2);
frame.setVisible(true);
}
}
public class Test extends JPanel implements ActionListener, MouseListener{
int y = 0, width, height, dy=0, maxHeight;
int BOTTOM;
Timer timer;
public Test(int width, int height, int BOTTOM, int SPEED){
setBackground(Color.BLUE);
this.width = width;
maxHeight = height;
this.BOTTOM = BOTTOM;
addMouseListener(this);
timer = new Timer(1000/SPEED, this);
timer.start();
}
public void move(){
if(y>=maxHeight){
dy = -1;
}
if(y<=0)
{
dy = 1;
}
y+=dy;
height+=dy;
//System.out.println(y);
repaint();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
if(y<=maxHeight/2) {
g.setColor(Color.green);
g.fillRect(0, BOTTOM - y, width, height);
}
if(y>=maxHeight/2 && y<(maxHeight/10)*9){
g.setColor(Color.green);
g.fillRect(0, BOTTOM-(maxHeight/2), width, maxHeight/2);
g.setColor(Color.green);
g.fillRect(0, BOTTOM - y, width, height-(maxHeight/2));
}
if(y>=(maxHeight/10)*9){
g.setColor(Color.green);
g.fillRect(0, BOTTOM-(maxHeight/2), width, maxHeight/2);
g.setColor(Color.green);
g.fillRect(0, BOTTOM-(9*(maxHeight/10)), width, (4*maxHeight)/10);
g.setColor(Color.green);
g.fillRect(0, BOTTOM - y, width, height-(9*(maxHeight)/10));
}
for(int i = 1; i<6; i++)
g.fillRect(0, BOTTOM - (i*(maxHeight/5)), width, 10);
System.out.println(y);
}
您的面板占用的空间少于 JFrame
,因为您的框架有标题栏和 window 边框。您可以在您的绘画方法中查询 'JPanel' 与您的 JPanel
的 getWidth()
和 getHeight()
使用的正确宽度和高度(换句话说,您的 JFrame 的宽度和高度与您的 JPanel 的宽度和高度不同,即使 JPanel 在边框之间视觉上占据了框架内的所有 space。
或者,如果您确实有不可能做到这一点的逻辑,您可以查询 insets of the frame 的大小,并从宽度中减去左右插入值,并将其作为宽度传递,并使用顶部和底部插入值对高度执行相同操作。
另一种方法是使用 pack()。它将框架的大小设置为框架内容的大小。在您的代码中,它看起来像这样:
frame.add(test2);
frame.pack();
如果您这样做,则不需要 frame.setSize() 调用。您可以使用 .add() 添加面板,也可以使用:
frame.setContentPane(test2);
所以我结合了您的评论并使其正常工作。这是有效的代码。
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("Pong");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(1,2));
Insets inset = frame.getInsets();
Test test2 = new Test(200-(inset.right + inset.left), 200 -(inset.top + inset.bottom), 200, 50);
frame.setContentPane(test2);
frame.pack();
frame.setVisible(true);
}
}
public class Test extends JPanel implements ActionListener, MouseListener{
int y = 0, width, height, dy=0, maxHeight;
int BOTTOM;
Timer timer;
Dimension size;
Insets inset;
public Test(int width, int height, int BOTTOM, int SPEED){
size = new Dimension(width, height);
setBackground(Color.BLUE);
setPreferredSize(size);
inset = this.getInsets();
this.width = width-(inset.right+inset.left);
maxHeight = height;
this.BOTTOM = BOTTOM - (inset.bottom+inset.top);
addMouseListener(this);
timer = new Timer(1000/SPEED, this);
timer.start();
}
public void move(){
if(y>=maxHeight){
dy = -1;
}
if(y<=0)
{
dy = 1;
}
y+=dy;
height+=dy;
//System.out.println(y);
repaint();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
if(y<=maxHeight/2) {
g.setColor(Color.green);
g.fillRect(0, BOTTOM - y, width, height);
}
if(y>=maxHeight/2 && y<(maxHeight/10)*9){
g.setColor(Color.green);
g.fillRect(0, BOTTOM - (maxHeight / 2), width, maxHeight / 2);
g.setColor(Color.green);
g.fillRect(0, BOTTOM - y, width, height-(maxHeight/2));
}
if(y>=(maxHeight/10)*9){
g.setColor(Color.green);
g.fillRect(0, BOTTOM-(maxHeight/2), width, maxHeight/2);
g.setColor(Color.green);
g.fillRect(0, BOTTOM-(9*(maxHeight/10)), width, (4*maxHeight)/10);
g.setColor(Color.green);
g.fillRect(0, BOTTOM - y, width, height-(9*(maxHeight)/10));
}
g.setColor(Color.white);
for(int i = 1; i<6; i++)
g.fillRect(0, BOTTOM - (i*(maxHeight/5)), width, 5);
}
- 覆盖
getPreferredSize
的 JPanel
,这将有助于布局管理器确定布局组件的最佳方式
- 使用
JFrame#pack
将框架边框环绕视图
- 使用
getWidth
和getHeight
获取面板的实际大小。当您需要知道这些值时,您应该这样做,不要长时间存储它们,因为这些值可能会改变
- 你也应该通读一下Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?
这是基于您的代码的基本示例...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test1 {
public static void main(String[] args) {
new Test1();
}
public Test1() {
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 class TestPane extends JPanel {
private int yPos;
private int dy = 1;
private int bottom = 50;
public TestPane() {
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
move();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
public void move() {
if (yPos >= getHeight()) {
dy = -1;
}
if (yPos <= 0) {
dy = 1;
}
yPos += dy;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int maxHeight = getHeight();
int width = getWidth();
int height = maxHeight;
if (yPos <= maxHeight / 2) {
g.setColor(Color.green);
g.fillRect(0, bottom - yPos, width, height);
}
if (yPos >= maxHeight / 2 && yPos < (maxHeight / 10) * 9) {
g.setColor(Color.green);
g.fillRect(0, bottom - (maxHeight / 2), width, maxHeight / 2);
g.setColor(Color.green);
g.fillRect(0, bottom - yPos, width, height - (maxHeight / 2));
}
if (yPos >= (maxHeight / 10) * 9) {
g.setColor(Color.green);
g.fillRect(0, bottom - (maxHeight / 2), width, maxHeight / 2);
g.setColor(Color.green);
g.fillRect(0, bottom - (9 * (maxHeight / 10)), width, (4 * maxHeight) / 10);
g.setColor(Color.green);
g.fillRect(0, bottom - yPos, width, height - (9 * (maxHeight) / 10));
}
for (int i = 1; i < 6; i++) {
g.fillRect(0, bottom - (i * (maxHeight / 5)), width, 10);
}
}
}
}
我有一个简单的动画代码,可以创建一个仪表类型的矩形效果。我想创建它以使其完全填满面板。我离得太近了,但它延伸到了底部的框架之外。我错过了什么?
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("Pong");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(1,2));
frame.setSize(500, 500);
//MouseTest test = new MouseTest();
Test test2 = new Test(frame.getWidth(), frame.getHeight(), frame.getHeight(), 50);
//frame.add(test);
frame.add(test2);
frame.setVisible(true);
}
}
public class Test extends JPanel implements ActionListener, MouseListener{
int y = 0, width, height, dy=0, maxHeight;
int BOTTOM;
Timer timer;
public Test(int width, int height, int BOTTOM, int SPEED){
setBackground(Color.BLUE);
this.width = width;
maxHeight = height;
this.BOTTOM = BOTTOM;
addMouseListener(this);
timer = new Timer(1000/SPEED, this);
timer.start();
}
public void move(){
if(y>=maxHeight){
dy = -1;
}
if(y<=0)
{
dy = 1;
}
y+=dy;
height+=dy;
//System.out.println(y);
repaint();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
if(y<=maxHeight/2) {
g.setColor(Color.green);
g.fillRect(0, BOTTOM - y, width, height);
}
if(y>=maxHeight/2 && y<(maxHeight/10)*9){
g.setColor(Color.green);
g.fillRect(0, BOTTOM-(maxHeight/2), width, maxHeight/2);
g.setColor(Color.green);
g.fillRect(0, BOTTOM - y, width, height-(maxHeight/2));
}
if(y>=(maxHeight/10)*9){
g.setColor(Color.green);
g.fillRect(0, BOTTOM-(maxHeight/2), width, maxHeight/2);
g.setColor(Color.green);
g.fillRect(0, BOTTOM-(9*(maxHeight/10)), width, (4*maxHeight)/10);
g.setColor(Color.green);
g.fillRect(0, BOTTOM - y, width, height-(9*(maxHeight)/10));
}
for(int i = 1; i<6; i++)
g.fillRect(0, BOTTOM - (i*(maxHeight/5)), width, 10);
System.out.println(y);
}
您的面板占用的空间少于 JFrame
,因为您的框架有标题栏和 window 边框。您可以在您的绘画方法中查询 'JPanel' 与您的 JPanel
的 getWidth()
和 getHeight()
使用的正确宽度和高度(换句话说,您的 JFrame 的宽度和高度与您的 JPanel 的宽度和高度不同,即使 JPanel 在边框之间视觉上占据了框架内的所有 space。
或者,如果您确实有不可能做到这一点的逻辑,您可以查询 insets of the frame 的大小,并从宽度中减去左右插入值,并将其作为宽度传递,并使用顶部和底部插入值对高度执行相同操作。
另一种方法是使用 pack()。它将框架的大小设置为框架内容的大小。在您的代码中,它看起来像这样:
frame.add(test2);
frame.pack();
如果您这样做,则不需要 frame.setSize() 调用。您可以使用 .add() 添加面板,也可以使用:
frame.setContentPane(test2);
所以我结合了您的评论并使其正常工作。这是有效的代码。
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame("Pong");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(1,2));
Insets inset = frame.getInsets();
Test test2 = new Test(200-(inset.right + inset.left), 200 -(inset.top + inset.bottom), 200, 50);
frame.setContentPane(test2);
frame.pack();
frame.setVisible(true);
}
}
public class Test extends JPanel implements ActionListener, MouseListener{
int y = 0, width, height, dy=0, maxHeight;
int BOTTOM;
Timer timer;
Dimension size;
Insets inset;
public Test(int width, int height, int BOTTOM, int SPEED){
size = new Dimension(width, height);
setBackground(Color.BLUE);
setPreferredSize(size);
inset = this.getInsets();
this.width = width-(inset.right+inset.left);
maxHeight = height;
this.BOTTOM = BOTTOM - (inset.bottom+inset.top);
addMouseListener(this);
timer = new Timer(1000/SPEED, this);
timer.start();
}
public void move(){
if(y>=maxHeight){
dy = -1;
}
if(y<=0)
{
dy = 1;
}
y+=dy;
height+=dy;
//System.out.println(y);
repaint();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
if(y<=maxHeight/2) {
g.setColor(Color.green);
g.fillRect(0, BOTTOM - y, width, height);
}
if(y>=maxHeight/2 && y<(maxHeight/10)*9){
g.setColor(Color.green);
g.fillRect(0, BOTTOM - (maxHeight / 2), width, maxHeight / 2);
g.setColor(Color.green);
g.fillRect(0, BOTTOM - y, width, height-(maxHeight/2));
}
if(y>=(maxHeight/10)*9){
g.setColor(Color.green);
g.fillRect(0, BOTTOM-(maxHeight/2), width, maxHeight/2);
g.setColor(Color.green);
g.fillRect(0, BOTTOM-(9*(maxHeight/10)), width, (4*maxHeight)/10);
g.setColor(Color.green);
g.fillRect(0, BOTTOM - y, width, height-(9*(maxHeight)/10));
}
g.setColor(Color.white);
for(int i = 1; i<6; i++)
g.fillRect(0, BOTTOM - (i*(maxHeight/5)), width, 5);
}
- 覆盖
getPreferredSize
的JPanel
,这将有助于布局管理器确定布局组件的最佳方式 - 使用
JFrame#pack
将框架边框环绕视图 - 使用
getWidth
和getHeight
获取面板的实际大小。当您需要知道这些值时,您应该这样做,不要长时间存储它们,因为这些值可能会改变 - 你也应该通读一下Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?
这是基于您的代码的基本示例...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test1 {
public static void main(String[] args) {
new Test1();
}
public Test1() {
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 class TestPane extends JPanel {
private int yPos;
private int dy = 1;
private int bottom = 50;
public TestPane() {
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
move();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
public void move() {
if (yPos >= getHeight()) {
dy = -1;
}
if (yPos <= 0) {
dy = 1;
}
yPos += dy;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int maxHeight = getHeight();
int width = getWidth();
int height = maxHeight;
if (yPos <= maxHeight / 2) {
g.setColor(Color.green);
g.fillRect(0, bottom - yPos, width, height);
}
if (yPos >= maxHeight / 2 && yPos < (maxHeight / 10) * 9) {
g.setColor(Color.green);
g.fillRect(0, bottom - (maxHeight / 2), width, maxHeight / 2);
g.setColor(Color.green);
g.fillRect(0, bottom - yPos, width, height - (maxHeight / 2));
}
if (yPos >= (maxHeight / 10) * 9) {
g.setColor(Color.green);
g.fillRect(0, bottom - (maxHeight / 2), width, maxHeight / 2);
g.setColor(Color.green);
g.fillRect(0, bottom - (9 * (maxHeight / 10)), width, (4 * maxHeight) / 10);
g.setColor(Color.green);
g.fillRect(0, bottom - yPos, width, height - (9 * (maxHeight) / 10));
}
for (int i = 1; i < 6; i++) {
g.fillRect(0, bottom - (i * (maxHeight / 5)), width, 10);
}
}
}
}