您需要跑到最近的布局管理器教程,而不是步行。在那里您会发现 JFrame 的 contentPane 默认使用 BorderLayout,并且当您将组件添加到使用 BorderLayout 的容器而不使用其他常量时,它会默认添加到 BorderLayout.CENTER 位置,覆盖之前添加的任何内容。
一种解决方案是创建另一个使用所选布局的 JPanel,甚至可能只是将其保留为 JPanel 的默认 FlowLayout,将您的组件添加到其中,然后将该 JPanel 添加到 JFrame。
IE,
ChartComponent ccOne = new ChartComponent(50, 50, 100, 200);
ChartComponent ccTwo = new ChartComponent(10, 10, 10, 10);
JPanel container = new JPanel(); // JPanel uses FlowLayout by default
container.add(ccOne);
container.add(ccTwo);
f.add(container, BorderLayout.CENTER); // just to be clear
f.pack();
f.setVisible(true);
请查看本教程链接: 在容器内布局组件
编辑
正如 MadProgrammer 指出的那样,这里还有另一个问题:
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(Color.RED);
g2.fillRect(w, h, x, y);
}
因为您不调用 super 方法,因此在需要时不会清除旧图像,如果您尝试通过更改 Swing 中的 w、h、x 或 y 来做一些动画,这将非常重要计时器。要解决这个问题,请务必调用 super 的方法。protected
此外,paintComponent不应该是public
,并且您应该使用@Override
注释来确保您正确地覆盖了该方法。如果您绝对需要创建一个新的 Graphics 上下文,那么您应该在完成后将其处理掉,以免资源耗尽。不要丢弃 JVM 提供给您的 Graphics 上下文(例如传递给您的方法参数的上下文,因为paintComponent(...)
这可能会产生不希望的副作用:
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(Color.RED);
g2.fillRect(w, h, x, y);
g2.dispose(); // only do this if you create your own Graphics context
}
编辑 2
此外,您应该养成尝试不设置任何大小的习惯,而是让 GUI 的组件和布局管理器在被要求时设置自己的大小,因为这将导致更令人愉悦和灵活的 GUI 程序.
编辑 3
您在评论中声明:
我修复了代码,但我似乎没有在任何地方出现 2 个红色方块,并且窗口以非常小的尺寸启动。我还有很多学习要做,我不明白为什么添加的代码会这样做。
您的问题是您的 JComponent,ChartComponent 的默认 preferredSize 将是 0,0 或 1,1;我忘了哪个,但没关系,因为在任何一种情况下,组件都不够大而无法看到。为了解决这个问题,给你的类一个 getPreferredSize() 方法覆盖,帮助设置它的大小。例如,:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.*;
public class BalanceChart {
Double[] Props = new Double[6];
public static void main(String[] args) {
JFrame f = new JFrame("Balance Chart");
// f.setSize(500, 500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ChartComponent ccOne = new ChartComponent(50, 50, 100, 200);
ChartComponent ccTwo = new ChartComponent(10, 10, 10, 10);
JPanel container = new JPanel();
container.add(ccOne);
container.add(ccTwo);
f.add(container);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
private void getProps() {
// ignore
}
}
class ChartComponent extends JComponent {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private int x, y, w, h;
public ChartComponent(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(Color.RED);
g2.fillRect(w, h, x, y);
g2.dispose();
}
}