调整 JPanel BorderLayout 的大小 Java
Resize a JPanel BorderLayout Java
我尝试使用 swing,但有一个小问题未能解决。我想做的很简单:我只想使用 BorderLayout 在 JFrame 中使用 JPanel。
问题是我的中心面板总是放在我的 North Jpanel 上方。事实上,无论我给北面板的大小是多少,在中心面板开始之后(就像这个 image)。
注意:当我将第二个面板放在南边时,第一个面板有足够的空间可以绘制,但即使它有更多的空间,第二个面板也只需要 10 个像素,这是不够的(就像这张图片)。
这是我的 Plateau 构造函数 class,它扩展了 JFrame:
public Plateau(){
super("arkanoid");
this.setLayout(new BorderLayout());
setFocusable(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().add(affich,BorderLayout.NORTH);
this.getContentPane().add(jeu, BorderLayout.CENTER);
setVisible(true);
this.setResizable(false);
this.setMinimumSize(new Dimension(700,800));
this.setLocationRelativeTo(null);
}
这里我面板的一部分放在中间(剩下的是dvariable修改和绘图函数):
public class Jeu extends JPanel {
public Jeu(int score, int plateauX, int balleX, int balleY, boolean perdu){
super();
}
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D)g;
this.setSize(new Dimension(Width,Heigth));
}
}
这是我所有的 class 应该在北方:
public class Affich extends JPanel {
public Affich() {
super();
this.setSize(100,100);
}
public void paint(Graphics g){
this.setSize(100,100);
g.drawOval(0, 0, 50, 50);
}
}
希望我说得够清楚
从不 在绘画方法中调用 setSize(...)
或类似的东西。这些方法应该只用于绘画和绘画,如果你试图改变大小状态,你可能会陷入无休止调用的恶性循环——设置大小调用重绘设置大小调用重绘。
改为:
- 重写 JPanel 的 paintComponent 而不是 绘画,因为绘画不仅仅负责绘制 JPanel,重写它可能会对 JPanel 的边框和子组件产生意想不到的后果。
- 在覆盖中调用超级的 paintComponent
- 再次仅在绘画方法中绘画
- 不设置大小,而是设置首选大小,并从调用一次的代码中设置,而不是在绘画方法中。
例如
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.*;
public class MyDrawing {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int affichW = 100;
int affichH = 100;
Affich affich = new Affich(affichW , affichH );
Jeu jeu = new Jeu();
frame.add(affich, BorderLayout.PAGE_START);
frame.add(jeu, BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
@SuppressWarnings("serial")
class Jeu extends JPanel {
private static final int JEU_W = 600;
private static final int JEU_H = 450;
public Jeu(int score, int plateauX, int balleX, int balleY, boolean perdu) {
super();
setBorder(BorderFactory.createTitledBorder("Jeu"));
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
} else {
return new Dimension(JEU_W, JEU_H);
}
}
public Jeu() {
this(0, 0, 0, 0, false);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// draw with g2 here
}
}
@SuppressWarnings("serial")
class Affich extends JPanel {
private int width = 0;
private int height = 0;
public Affich(int width, int height) {
super();
this.width = width;
this.height = height;
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
} else {
return new Dimension(width, height);
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// draw smooth oval
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawOval(0, 0, 50, 50);
}
}
我尝试使用 swing,但有一个小问题未能解决。我想做的很简单:我只想使用 BorderLayout 在 JFrame 中使用 JPanel。 问题是我的中心面板总是放在我的 North Jpanel 上方。事实上,无论我给北面板的大小是多少,在中心面板开始之后(就像这个 image)。
注意:当我将第二个面板放在南边时,第一个面板有足够的空间可以绘制,但即使它有更多的空间,第二个面板也只需要 10 个像素,这是不够的(就像这张图片)。
这是我的 Plateau 构造函数 class,它扩展了 JFrame:
public Plateau(){
super("arkanoid");
this.setLayout(new BorderLayout());
setFocusable(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.getContentPane().add(affich,BorderLayout.NORTH);
this.getContentPane().add(jeu, BorderLayout.CENTER);
setVisible(true);
this.setResizable(false);
this.setMinimumSize(new Dimension(700,800));
this.setLocationRelativeTo(null);
}
这里我面板的一部分放在中间(剩下的是dvariable修改和绘图函数):
public class Jeu extends JPanel {
public Jeu(int score, int plateauX, int balleX, int balleY, boolean perdu){
super();
}
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D)g;
this.setSize(new Dimension(Width,Heigth));
}
}
这是我所有的 class 应该在北方:
public class Affich extends JPanel {
public Affich() {
super();
this.setSize(100,100);
}
public void paint(Graphics g){
this.setSize(100,100);
g.drawOval(0, 0, 50, 50);
}
}
希望我说得够清楚
从不 在绘画方法中调用 setSize(...)
或类似的东西。这些方法应该只用于绘画和绘画,如果你试图改变大小状态,你可能会陷入无休止调用的恶性循环——设置大小调用重绘设置大小调用重绘。
改为:
- 重写 JPanel 的 paintComponent 而不是 绘画,因为绘画不仅仅负责绘制 JPanel,重写它可能会对 JPanel 的边框和子组件产生意想不到的后果。
- 在覆盖中调用超级的 paintComponent
- 再次仅在绘画方法中绘画
- 不设置大小,而是设置首选大小,并从调用一次的代码中设置,而不是在绘画方法中。
例如
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.*;
public class MyDrawing {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int affichW = 100;
int affichH = 100;
Affich affich = new Affich(affichW , affichH );
Jeu jeu = new Jeu();
frame.add(affich, BorderLayout.PAGE_START);
frame.add(jeu, BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
@SuppressWarnings("serial")
class Jeu extends JPanel {
private static final int JEU_W = 600;
private static final int JEU_H = 450;
public Jeu(int score, int plateauX, int balleX, int balleY, boolean perdu) {
super();
setBorder(BorderFactory.createTitledBorder("Jeu"));
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
} else {
return new Dimension(JEU_W, JEU_H);
}
}
public Jeu() {
this(0, 0, 0, 0, false);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// draw with g2 here
}
}
@SuppressWarnings("serial")
class Affich extends JPanel {
private int width = 0;
private int height = 0;
public Affich(int width, int height) {
super();
this.width = width;
this.height = height;
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
} else {
return new Dimension(width, height);
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// draw smooth oval
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawOval(0, 0, 50, 50);
}
}