/**
* SiebenSegmentAnzeige
* by Christian Götz
* 27.02.2007
*
*
* Eine Siebensegmentanzeige in Form einer Swingkomponente
* Das ideale Größenverhältnis der Anzeige ist width/height = 12/20
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager;
import java.awt.geom.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class SiebenSegmentAnzeige extends JPanel {
public static final float MIN_WIDTH = 12, MIN_HEIGHT = 20;
private static final boolean[]
NUMBER_0 = new boolean[] {true, true, true, true, true, true, false},
NUMBER_1 = new boolean[] {false, true, true, false, false, false, false},
NUMBER_2 = new boolean[] {true, true, false, true, true, false, true},
NUMBER_3 = new boolean[] {true, true, true, true, false, false, true},
NUMBER_4 = new boolean[] {false, true, true, false, false, true, true},
NUMBER_5 = new boolean[] {true, false, true, true, false, true, true},
NUMBER_6 = new boolean[] {true, false, true, true, true, true, true},
NUMBER_7 = new boolean[] {true, true, true, false, false, true, false},
NUMBER_8 = new boolean[] {true, true, true, true, true, true, true},
NUMBER_9 = new boolean[] {true, true, true, true, false, true, true};
private boolean[] segment = NUMBER_0.clone();
private boolean paintSegmentBorder = true;
private Color borderColor = Color.GRAY;
public SiebenSegmentAnzeige()
{
super();
init();
}
public SiebenSegmentAnzeige(boolean isDoubleBuffered)
{
super(isDoubleBuffered);
init();
}
public SiebenSegmentAnzeige(LayoutManager layout, boolean isDoubleBuffered)
{
super(layout, isDoubleBuffered);
init();
}
public SiebenSegmentAnzeige(LayoutManager layout)
{
super(layout);
init();
}
private void init()
{
setForeground(Color.RED);
setSize((int)MIN_WIDTH, (int)MIN_HEIGHT);
setPreferredSize(new Dimension((int)MIN_WIDTH*2, (int)MIN_HEIGHT*2));
setMinimumSize(new Dimension((int)MIN_WIDTH, (int)MIN_HEIGHT));
}
/**Malt einen Rahmen um die einzelnen Segmente. Die Farbe kann mit setSegmentBorderColor(Color c) eingestellt werden.
*
* @param b
*/
public void paintSegmentBorder(boolean b)
{
paintSegmentBorder = b;
}
/** gibt true zurück wenn ein Rahmen um die Segmente gezeichnet wird.
*
* @return
*/
public boolean isPaintingSegmentBorder()
{
return paintSegmentBorder;
}
/** gibt die Farbe des Segmentrahmen zurück.
*
* @return die Farbe des Segmentrahmen.
*/
public Color getSegmentBorderColor()
{
return borderColor;
}
/** setzt die Farbe des Segmentrahmen.
*
* @param c die Farbe des Segmentrahmen.
*/
public void setSegmentBorderColor(Color c)
{
borderColor = c;
repaint();
}
/** läßt die Anzeige eine Zahl zwischen 0 und 9 anzeigen.
*
* @param num
*/
public void showNumber(int num)
{
if(num < 0) num = 0;
else if(num > 9) num = 9;
switch(num)
{
case 0:
segment = NUMBER_0.clone();
break;
case 1:
segment = NUMBER_1.clone();
break;
case 2:
segment = NUMBER_2.clone();
break;
case 3:
segment = NUMBER_3.clone();
break;
case 4:
segment = NUMBER_4.clone();
break;
case 5:
segment = NUMBER_5.clone();
break;
case 6:
segment = NUMBER_6.clone();
break;
case 7:
segment = NUMBER_7.clone();
break;
case 8:
segment = NUMBER_8.clone();
break;
case 9:
segment = NUMBER_9.clone();
break;
}
repaint();
}
/** schaltet ein einzelnes Segment (0-6) ein oder aus
*
* @param segment das Segment das geschaltet werden soll
* @param state true schaltet das Segment ein, false aus.
*/
public void setSegment(int segment, boolean state)
{
if(segment < 0) segment = 0;
else if(segment > 6) segment = 6;
this.segment[segment] = state;
repaint();
}
/** schaltet alle 7 Segmente an oder aus.
*
* @param state true schaltet die Segmente ein, false aus.
*/
public void setAllSegments(boolean state)
{
for (int i=0 ; i<7 ; i++)
{
segment[i] = state;
}
repaint();
}
/** zeigt eine Counteranimation. Es wird von der Zahl from
* bis einschließlich der Zahl too gezählt.
*
* @param from Die Zahl von der aus gezählt wird.
* @param to Die Zahl bis zu der einschließlich gezählt wird.
* @param delayInMilliSeconds Die Zeit die zwischen den einzelnen Zählschritten gewartet
* wird in Millisekunden.
* @param extraThread wenn true wird der Counter in einem eigenen Thread gestarted.
*/
public void showCounter(int from, int to, final int delayInMilliSeconds, boolean extraThread)
{
if(from < 0) from = 0;
else if(from > 9) from = 9;
if(to < 0) to = 0;
else if(to > 9) to = 9;
if(from != to)
{
int d;
if(from < to) d = 1;
else d = -1;
final int f = from, t = to, direction = d;
Thread thread = new Thread(new Runnable()
{
public void run()
{
for(int num=f ; num != t+direction ; num += direction)
{
showNumber(num);
try {Thread.sleep(delayInMilliSeconds);}catch(InterruptedException e) {}
}
}
});
if(extraThread) thread.start();
else thread.run();
}
}
@Override
public void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D) gr;
for(int i=0 ; i<segment.length ; i++)
{
if(segment[i]) paintSegment(g, i);
}
}
private void paintSegment(Graphics2D g, int segment)
{
switch(segment)
{
// Horizontale Segmente:
case 0:
paintHorizontalSegment(g, 0);
break;
case 6:
paintHorizontalSegment(g, 8);
break;
case 3:
paintHorizontalSegment(g, 16);
break;
// Vertikale Segmente:
case 5:
paintVerticalSegment(g, 0, 0);
break;
case 1:
paintVerticalSegment(g, 0, 8);
break;
case 4:
paintVerticalSegment(g, 8, 0);
break;
case 2:
paintVerticalSegment(g, 8, 8);
break;
}
}
private void paintHorizontalSegment(Graphics2D g, int row)
{
float fieldWidth = (getWidth())/12f;
float fieldHeight = (getHeight())/20f;
Path2D.Float polygon1 = new Path2D.Float();
Path2D.Float polygon2 = new Path2D.Float();
Path2D.Float border = new Path2D.Float();
Rectangle2D.Float rect = new Rectangle2D.Float();
polygon1.moveTo(fieldWidth*2, fieldHeight*2 + row*fieldHeight);
polygon1.lineTo(fieldWidth*3, fieldHeight + row*fieldHeight);
polygon1.lineTo(fieldWidth*3, fieldHeight*3 + row*fieldHeight);
polygon1.lineTo(fieldWidth*2, fieldHeight*2 + row*fieldHeight);
rect.setRect(fieldWidth*3, fieldHeight + row*fieldHeight,
fieldWidth*6, fieldHeight*2);
polygon2.moveTo(fieldWidth*9, fieldHeight + row*fieldHeight);
polygon2.lineTo(fieldWidth*10, fieldHeight*2 + row*fieldHeight);
polygon2.lineTo(fieldWidth*9, fieldHeight*3 + row*fieldHeight);
polygon2.lineTo(fieldWidth*9, fieldHeight + row*fieldHeight);
g.setPaint(getForeground());
g.fill(polygon1);
g.fill(rect);
g.fill(polygon2);
if(paintSegmentBorder)
{
border.moveTo(fieldWidth*2, fieldHeight*2 + row*fieldHeight);
border.lineTo(fieldWidth*3, fieldHeight + row*fieldHeight);
border.lineTo(fieldWidth*9, fieldHeight + row*fieldHeight);
border.lineTo(fieldWidth*10, fieldHeight*2 + row*fieldHeight);
border.lineTo(fieldWidth*9, fieldHeight*3 + row*fieldHeight);
border.lineTo(fieldWidth*3, fieldHeight*3 + row*fieldHeight);
border.lineTo(fieldWidth*2, fieldHeight*2 + row*fieldHeight);
g.setPaint(borderColor);
g.draw(border);
}
}
private void paintVerticalSegment(Graphics2D g, int row, int column)
{
float fieldWidth = (getWidth())/12f;
float fieldHeight = (getHeight())/20f;
Path2D.Float polygon1 = new Path2D.Float();
Path2D.Float polygon2 = new Path2D.Float();
Path2D.Float border = new Path2D.Float();
Rectangle2D.Float rect = new Rectangle2D.Float();
polygon1.moveTo(fieldWidth*2 + column*fieldWidth, fieldHeight*2 + row*fieldHeight);
polygon1.lineTo(fieldWidth*3 + column*fieldWidth, fieldHeight*3 + row*fieldHeight);
polygon1.lineTo(fieldWidth + column*fieldWidth, fieldHeight*3 + row*fieldHeight);
polygon1.lineTo(fieldWidth*2 + column*fieldWidth, fieldHeight*2 + row*fieldHeight);
rect.setRect(fieldWidth + column*fieldWidth, fieldHeight*3 + row*fieldHeight,
fieldWidth*2, fieldHeight*6);
polygon2.moveTo(fieldWidth + column*fieldWidth, fieldHeight*9 + row*fieldHeight);
polygon2.lineTo(fieldWidth*3 + column*fieldWidth, fieldHeight*9 + row*fieldHeight);
polygon2.lineTo(fieldWidth*2 + column*fieldWidth, fieldHeight*10 + row*fieldHeight);
polygon2.lineTo(fieldWidth + column*fieldWidth, fieldHeight*9 + row*fieldHeight);
g.setPaint(getForeground());
g.fill(polygon1);
g.fill(rect);
g.fill(polygon2);
if(paintSegmentBorder)
{
border.moveTo(fieldWidth*2 + column*fieldWidth, fieldHeight*2 + row*fieldHeight);
border.lineTo(fieldWidth*3 + column*fieldWidth, fieldHeight*3 + row*fieldHeight);
border.lineTo(fieldWidth*3 + column*fieldWidth, fieldHeight*9 + row*fieldHeight);
border.lineTo(fieldWidth*2 + column*fieldWidth, fieldHeight*10 + row*fieldHeight);
border.lineTo(fieldWidth + column*fieldWidth, fieldHeight*9 + row*fieldHeight);
border.lineTo(fieldWidth + column*fieldWidth, fieldHeight*3 + row*fieldHeight);
border.lineTo(fieldWidth*2 + column*fieldWidth, fieldHeight*2 + row*fieldHeight);
g.setPaint(borderColor);
g.draw(border);
}
}
/* Testing... ;-) */
public static void main(String[] args)
{
JFrame frame = new JFrame("7-Segment");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 300);
JPanel cp = (JPanel) frame.getContentPane();
cp.setLayout(null);
SiebenSegmentAnzeige anz = new SiebenSegmentAnzeige();
anz.setSize(anz.getPreferredSize());
anz.setBorder(new LineBorder(Color.BLACK));
// anz.setSize(120, 200);
anz.setLocation(50, 50);
cp.add(anz);
anz.setAllSegments(false);
anz.setForeground(Color.CYAN);
frame.setVisible(true);
for(int j = 0 ; j < 3 ; j++)
{
for(int i = 0 ; i < 6 ; i++)
{
anz.setSegment(i, true);
if (i > 0) anz.setSegment(i - 1, false);
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
}
}
anz.setAllSegments(false);
switch(j)
{
case 0:
anz.setForeground(Color.BLUE);
break;
case 1:
anz.setForeground(Color.YELLOW);
break;
}
}
anz.setForeground(Color.RED);
anz.showCounter(9, 0, 600, false);
anz.showNumber(0);
anz.setForeground(Color.BLUE);
anz.setSegmentBorderColor(Color.CYAN);
}
}