繁体   English   中英

在JFrame中添加来自同一类的两个组件

[英]Adding two components from the same class in a JFrame

因此,对于某些作业,我必须创建一个代表余额的条形图。 为了熟悉图形/组件,我只想在屏幕上放置两个框。 似乎第一个框被“绘制”,然后第二个框被覆盖? 这是两个类。

主类-BalanceChart.java

package balancechart;

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);
   f.add(ccOne);
   f.add(ccTwo);
   f.setVisible(true);
}

private void getProps(){
    //ignore
}

}

组件类-ChartComponent.java

package balancechart;

import javax.swing.*;
import java.awt.*;

public class ChartComponent 
extends JComponent {

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;
}

public void paintComponent(Graphics g){
  Graphics2D g2 = (Graphics2D) g.create();
  g2.setColor(Color.RED);
  g2.fillRect(w, h, x, y);
}

}

我想这与我对JFrame的2种添加过程有关,但我不确定该如何做。

提前致谢

您需要跑步而不是步行到最近的布局管理器教程。 在那里,您会发现JFrame的contentPane默认情况下使用BorderLayout,并且当您将组件添加到使用BorderLayout的容器中而没有其他常量时,默认情况下会将其添加到BorderLayout.CENTER位置,包括之前添加的所有内容。

一种解决方案是创建另一个使用选择的布局的JPanel,甚至将其保留为JPanel的默认FlowLayout,然后将组件添加到其中,然后将该JPanel添加到JFrame。

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的方法。 另外,paintComponent应该被protected而不是public ,并且应该使用@Override批注以确保正确覆盖了该方法。 并且,如果您绝对需要创建一个新的Graphics上下文,则应在完成后处置它,以免耗尽资源。 处置由JVM(如一个传递到你的给你一个图形上下文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();
   }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM