我对这一个人感到很茫然。我正在尝试创建一个自定义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.我不是一个可以放弃的人,但是这个程序让我想要改变我的专业。
答案 0 :(得分:3)
您需要在此处考虑几个问题:
每个Bar
对象都需要自己的变量来跟踪其状态。这意味着Bar
中的成员变量不应该是静态的。
自定义组件需要覆盖getPreferredSize()
才能告诉其父容器自定义组件想要占用多少空间。
父容器负责确定其包含的组件的位置。 (更合适的是,这是LayoutManager的责任。)这意味着在自定义组件中具有x和y位置是不合适的。
在paintComponent(Graphics g)
中,您只能在组件拥有的区域内进行绘制。坐标相对于组件的左上角,不相对于容纳它的容器的左上角。这意味着您需要绘制一个覆盖整个组件的矩形:
g.drawRectangle(0, 0, getWidth(), getHeight());
您可以使用数组或List
将Bar
对象存储在自定义面板中,从而降低代码的复杂性。例如,您可以在一个简单的for循环中绘制每个Bar
。
答案 1 :(得分:3)
所以你非常接近。我认为你能做的最好的事情就是比使用ArrayList更复杂,只需使用已经存在的组件。这是使用HorizontalBox的一个更简单的例子。
我只展示一个方向和一个大小,但我认为你可以自己完成剩下的工作。 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 );
}
} );
}
}