获取自定义JPanel以显示自定义JComponents(Java Swing)

时间:2014-10-26 01:56:53

标签: java swing jpanel jcomponent

我对这一个人感到很茫然。我正在尝试创建一个自定义LED显示屏来显示排列为8的7个条形图。我有一个自定义的JComponent(条形图)显示在JFrame内部,但我无法显示自定义面板内部的条形图我是创建。下面是我的类中构造函数方法和paint方法的代码,以及我用来测试这些类的主要方法。

自定义JComponent:

public class Bar extends JComponent
{
    // instance variables - replace the example below with your own
    private static boolean litUp = false;
    private static boolean vertical = false;
    private static boolean rotated = false;
    private static boolean rotClockwise = false;
    private static int positionX;
    private static int positionY;



    public Bar(boolean lit, boolean vert, int posX, int posY)
    {
        litUp = lit;
        vertical = vert;
        positionX = posX;
        positionY = posY;
        repaint();
        System.out.println("The bar is being initialized");
    }
    public void paintComponent(Graphics g)
    {
        System.out.println("BAR: Paint Component being called");

        super.paintComponent(g);
        Graphics2D g2D = (Graphics2D)g;

        if(vertical == true)
        {
            if(litUp == true)
            {
                g2D.setColor(Color.red);
            }
            else
            {
                g2D.setColor(Color.black);
            }

            g2D.drawRect(positionX , positionY, 10, 30);
            g2D.fillRect(positionX , positionY, 10, 30);
            System.out.println("BAR: fillRect is being called for a vertical bar");
            if(rotated == true)
            {
                if(rotClockwise == true)
                {
                    g2D.rotate(0.3398);
                }
                else
                {
                    g2D.rotate(-0.3398);
                }
            }

        }

        else{

            System.out.println("BAR: fillRect is being called for a horizontal bar");
            if(litUp == true)
            {
                g2D.setColor(Color.red);
            }
            else
            {
                g2D.setColor(Color.black);
            }
            g2D.drawRect(positionX,positionY, 30, 10);
            g2D.fillRect(positionX,positionY, 30, 10);
        }


    }
}

自定义JPanel:

public class LED extends JPanel
{
    // instance variables - replace the example below with your own
    //private static Bar[] bars = new Bar[7];
    //private static int xPos;
    //private static int yPos;

    private  Bar barZero;
    private  Bar barOne;
    private  Bar barTwo;
    private  Bar barThree;
    private  Bar barFour;
    private  Bar barFive;
    private  Bar barSix;




    /**
     * Constructor for objects of class LED
     */
    public LED()
    {
        barZero = new Bar(false, false,  0, 0);
        this.add(barZero);
       // barZero.setDirection(false);
        barOne = new Bar(false, true, 0, 11);
        this.add(barOne);
        //barOne.setDirection(true);
        barTwo = new Bar(false, true, 20, 11);
        this.add(barTwo);
        //barTwo.setDirection(true);
        barThree = new Bar(false, false, 0, 42);
        this.add(barThree);
        //barThree.setDirection(false);
        barFour = new Bar(false, true, 0, 53);
        this.add(barFour);
        //barFour.setDirection(true);
        barFive = new Bar(false, true, 20, 53);
        this.add(barFive);
        //barFive.setDirection(true);
        barSix = new Bar(false, false, 0, 64);
        this.add(barSix);
        //barSix.setDirection(false);



        System.out.println("The LED class is being accessed");

        repaint();
    }

@ Override public void paintComponent(Graphics g)
    {
        System.out.println("LED: PaintComponent being called");
        //barOne.paintComponent(g);
        System.out.println("LED: barZero being painted| " + barZero.orientation() + "|  " + barZero.coordX());

        System.out.println("LED: barOne being painted| " + barOne.orientation() + "|  " + barOne.coordX());
        //barTwo.paintComponent(g);
        System.out.println("LED: barTwo being painted| " + barTwo.orientation() + "|  " + barTwo.coordX());

        //barThree.paintComponent(g);
        System.out.println("LED: barThree being painted| " + barThree.orientation() + "|  " + barThree.coordX());
        //barFour.paintComponent(g);
        System.out.println("LED: barFour being painted| " + barFour.orientation() + "|  " + barFour.coordX());
        //barFive.paintComponent(g);
        System.out.println("LED: barFive being painted| " + barFive.orientation() + "|  " + barFive.coordX());
        //barSix.paintComponent(g);
        System.out.println("LED: barSix being painted| " + barSix.orientation() + "|  " + barSix.coordX());


        super.paintComponent(g);
    }
}

测试员方法:

public class DrawRect {
  public static void main(String[] a) {
    JFrame window = new JFrame();
    LED led = new LED()
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setBounds(30, 30, 300, 300);
    window.getContentPane().add(led);
    window.setVisible(true);
  }
}

我可以初始化一个条形图并让它显示在框架中,但我无法让LED(面板)显示条形图。此外,这是从测试组件打印出来的字符串。我添加的任何栏都没有设置它们的值:它们都是水平的,它们的x位置都设置为0.我不是一个可以放弃的人,但是这个程序让我想要改变我的专业。

2 个答案:

答案 0 :(得分:3)

您需要在此处考虑几个问题:

  1. 每个Bar对象都需要自己的变量来跟踪其状态。这意味着Bar中的成员变量应该是静态的。

  2. 自定义组件需要覆盖getPreferredSize()才能告诉其父容器自定义组件想要占用多少空间。

  3. 父容器负责确定其包含的组件的位置。 (更合适的是,这是LayoutManager的责任。)这意味着在自定义组件中具有x和y位置是不合适的。

  4. paintComponent(Graphics g)中,您只能在组件拥有的区域内进行绘制。坐标相对于组件的左上角,相对于容纳它的容器的左上角。这意味着您需要绘制一个覆盖整个组件的矩形:

    g.drawRectangle(0, 0, getWidth(), getHeight());
    
  5. 您可以使用数组或ListBar对象存储在自定义面板中,从而降低代码的复杂性。例如,您可以在一个简单的for循环中绘制每个Bar

答案 1 :(得分:3)

所以你非常接近。我认为你能做的最好的事情就是比使用ArrayList更复杂,只需使用已经存在的组件。这是使用Horizo​​ntalBox的一个更简单的例子。

我只展示一个方向和一个大小,但我认为你可以自己完成剩下的工作。 paintComponent()例程中可能存在错误,该错误被一个像素关闭。我无法在屏幕上眯着眼睛确定。

也不要忘记整个多线程的事情。请在事件发送线程上。我的IDE中有几个宏,基本上可以在大约两秒钟内为EDT构建代码。没有任何借口。

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.Box;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class LedBar extends JComponent
{
   private final Dimension SIZE = new Dimension( 20, 50 );
   private float value = 50f; // range 0-100

   public void setValue( float value )
   {
      this.value = value;
   }

   public float getValue()
   {
      return value;
   }

   @Override
   public void paintComponent( Graphics g ) {
      super.paintComponent( g );
      g.setColor( Color.RED );
      g.drawRect( 0, 0, SIZE.width, SIZE.height );
      g.setColor( Color.RED.darker() );
      final int top = (int)(SIZE.height*(100f-value)/100f+1);
      final int bottom = (int)(SIZE.height*(value)/100f-1);
      g.fillRect( 1, top, SIZE.width-1, bottom);
   }

   @Override
   public Dimension getPreferredSize() {
      return SIZE;
   }
}

class Test
{
   public static void main( String[] args ) {
      SwingUtilities.invokeLater( new Runnable() {
         public void run() {
            JFrame frame = new JFrame();

            Box hbox = Box.createHorizontalBox();
            for (int i = 0; i < 5; i++) {
               LedBar led = new LedBar();
               led.setValue( i * 20f );
               hbox.add( led );
            }
            frame.add( hbox );

            frame.pack();
            frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
            frame.setLocationRelativeTo( null );
            frame.setVisible( true );
         }
      } );
   }
}