简体   繁体   English

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

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

So for some homework I have to create a bar chart that represents balances. 因此,对于某些作业,我必须创建一个代表余额的条形图。 Just to get familiar with graphics/components I just want to start of by placing two boxes on the screen. 为了熟悉图形/组件,我只想在屏幕上放置两个框。 It seems the first box is 'drawn' then the second box just overwrites it? 似乎第一个框被“绘制”,然后第二个框被覆盖? Here are the two classes. 这是两个类。

Main Class - BalanceChart.java 主类-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
}

}

Component class - ChartComponent.java 组件类-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);
}

}

I guess it has something to do with the 2 add procedures I have for the JFrame, I'm just not sure how to go about it. 我想这与我对JFrame的2种添加过程有关,但我不确定该如何做。

Thanks in advance 提前致谢

You need to run, not walk, to the nearest layout manager tutorial. 您需要跑步而不是步行到最近的布局管理器教程。 There you'll find out that a JFrame's contentPane uses BorderLayout by default and that when you add a component to a BorderLayout-using container without additional constants, it is added by default to the BorderLayout.CENTER position, covering anything added previously. 在那里,您会发现JFrame的contentPane默认情况下使用BorderLayout,并且当您将组件添加到使用BorderLayout的容器中而没有其他常量时,默认情况下会将其添加到BorderLayout.CENTER位置,包括之前添加的所有内容。

A solution is to create another JPanel that uses a layout of choice, perhaps even just leaving it with JPanel's default FlowLayout, adding your components to it, and then adding that JPanel to the JFrame. 一种解决方案是创建另一个使用选择的布局的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);

Please check out this tutorial link: Laying Out Components Within a Container 请查看此教程链接: 在容器中布置组件


Edit 编辑
As MadProgrammer points out, you've another problem here: 正如MadProgrammer指出的那样,您在这里还有另一个问题:

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

in that you don't call the super method, and so old images won't be cleared when needed, and this will matter greatly if you try to do some animation say by changing your w, h, x, or y in a Swing Timer. 因为您不会调用super方法,因此在需要时不会清除旧图像,如果您尝试通过在Swing中更改w,h,x或y来做一些动画说明,这将非常重要计时器。 To solve this, be sure to call the super's method. 要解决此问题,请务必调用super的方法。 Also, paintComponent should be protected not public , and you should use the @Override annotation to be sure that you're correctly overriding the method. 另外,paintComponent应该被protected而不是public ,并且应该使用@Override批注以确保正确覆盖了该方法。 And if you absolutely need to create a new Graphics context, then you should dispose of it when done so as not to run out of resources. 并且,如果您绝对需要创建一个新的Graphics上下文,则应在完成后处置它,以免耗尽资源。 Do not dispose of a Graphics context given to you by the JVM (such as the one passed into your paintComponent(...) method's parameter, as that can have unwanted side effects: 处置由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
}

Edit 2 编辑2
Also, you should get in the habit of trying not to set the sizes of anything, but instead letting the GUI's components and layout managers set their own size when asked to do so as this will lead to a more pleasing and flexible GUI program. 另外,您应该养成不要设置任何大小的习惯,而应让GUI的组件和布局管理器在需要时设置自己的大小,因为这将导致更加愉悦和灵活的GUI程序。


Edit 3 编辑3
You state in comment: 您发表评论:

I fixed up the code but I don't seem to have the 2 red squares appear anywhere and the window starts up in a really small size. 我修复了代码,但是似乎没有2个红色正方形出现在任何地方,并且窗口以很小的尺寸启动。 I still have a lot of learning to do and I can't see why the added code would of done this. 我仍然有很多学习要做,我看不出为什么添加的代码可以做到这一点。

Your problem is that your JComponent, the ChartComponent's default preferredSize will be either 0,0 or 1,1; 您的问题是您的JComponent(ChartComponent的默认preferredSize)将为0,0或1,1; I forgot which, but it doesn't matter, since in either case, the component won't be big enough to be seen. 我忘记了,但是没关系,因为在任何一种情况下,组件的大小都不足以被看到。 To solve this, give your class a getPreferredSize() method override that helps set its size. 要解决此问题,请为您的类提供一个getPreferredSize()方法重写,以帮助设置其大小。 eg,: 例如,:

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