1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sourceforge.jbarcodebean;
20
21 import javax.swing.*;
22 import java.awt.*;
23 import java.awt.geom.*;
24 import javax.accessibility.*;
25
26 import net.sourceforge.jbarcodebean.model.BarcodeStrategy;
27 import net.sourceforge.jbarcodebean.model.Codabar;
28 import net.sourceforge.jbarcodebean.model.Codabar_2to1;
29 import net.sourceforge.jbarcodebean.model.Code128;
30 import net.sourceforge.jbarcodebean.model.Code39;
31 import net.sourceforge.jbarcodebean.model.Code39_2to1;
32 import net.sourceforge.jbarcodebean.model.Ean13;
33 import net.sourceforge.jbarcodebean.model.Ean8;
34 import net.sourceforge.jbarcodebean.model.ExtendedCode39;
35 import net.sourceforge.jbarcodebean.model.ExtendedCode39_2to1;
36 import net.sourceforge.jbarcodebean.model.Interleaved25;
37 import net.sourceforge.jbarcodebean.model.Interleaved25_2to1;
38 import net.sourceforge.jbarcodebean.model.MSI;
39
40 import java.io.*;
41 import java.net.URL;
42 import java.util.Properties;
43 import java.awt.image.*;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 public class JBarcodeBean extends JComponent implements java.io.Serializable, Accessible {
101
102
103
104
105 private static final String SHOW_TEXT_CHANGED_PROPERTY = "showText";
106
107 private static final String CODE_CHANGED_PROPERTY = "code";
108
109 private static final String CODE_TYPE_CHANGED_PROPERTY = "codeType";
110
111 private static final String CHECK_DIGIT_CHANGED_PROPERTY = "checkDigit";
112
113 private static final String NARROWEST_BAR_WIDTH_CHANGED_PROPERTY = "narrowestBarWidth";
114
115 private static final String BARCODE_HEIGHT_CHANGED_PROPERTY = "barcodeHeight";
116
117 private static final String BARCODE_BACKGROUND_CHANGED_PROPERTY = "barcodeBackground";
118
119 private static final String ANGLE_DEGREES_CHANGED_PROPERTY = "angleDegrees";
120
121
122
123
124 private static final String HORIZONTAL_ALIGNMENR_PROPERTY ="horizontalAlignment";
125
126
127
128
129
130 public static final int ALIGN_LEFT =1;
131
132
133
134
135
136 public static final int ALIGN_CENTER =2;
137
138
139
140
141
142 public static final int ALIGN_RIGHT =3;
143
144
145
146
147
148 private static final String LABEL_POSITION_PROPERTY ="labelPosition";
149
150
151
152
153
154 public static final int LABEL_TOP = 1;
155
156
157
158
159
160 public static final int LABEL_BOTTOM = 2;
161
162
163
164
165
166 public static final int LABEL_NONE = 0;
167
168
169
170
171 private String code;
172 private BarcodeStrategy codeType;
173 private boolean checkDigit = false;
174 private EncodedBarcode encoded = null;
175 private int narrowestBarWidth = 1;
176 private int barcodeHeight = 40;
177 private Color barcodeBackground = Color.white;
178 private Dimension minimumSize;
179 private Dimension preferredSize;
180 private double angleDegrees;
181 private int labelHeight;
182 private int labelWidth;
183 private int barcodeWidth;
184 private String encodeError = "";
185 private int horizontalAlignment = ALIGN_CENTER;
186 private int labelPosition = LABEL_BOTTOM;
187
188
189
190
191
192
193
194 public JBarcodeBean(String code, BarcodeStrategy codeType) {
195
196
197 setForeground(Color.black);
198 setFont(new Font("Monospaced", Font.PLAIN, 12));
199
200
201 this.code = code;
202 this.codeType = codeType;
203 if (codeType.requiresChecksum() == BarcodeStrategy.MANDATORY_CHECKSUM) {
204 checkDigit = true;
205 } else if (codeType.requiresChecksum() == BarcodeStrategy.NO_CHECKSUM) {
206 checkDigit = false;
207 }
208
209
210 setDoubleBuffered(false);
211
212
213 encode();
214 recalculateSizes();
215 repaint();
216 }
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231 public JBarcodeBean() {
232 this("1234", new Code39());
233 }
234
235
236
237
238
239
240 public double getAngleDegrees() {
241 return angleDegrees;
242 }
243
244
245
246
247
248
249 public void setAngleDegrees(double angleDegrees) {
250 double oldValue = this.angleDegrees;
251 this.angleDegrees = angleDegrees;
252 firePropertyChange(ANGLE_DEGREES_CHANGED_PROPERTY, oldValue, angleDegrees);
253 recalculateSizes();
254 repaint();
255 }
256
257
258
259
260
261
262
263
264
265 public boolean isShowText() {
266 return this.labelPosition==LABEL_BOTTOM;
267 }
268
269
270
271
272
273
274
275
276
277
278 public void setShowText(boolean showText) {
279 boolean oldValue = isShowText();
280 setLabelPosition(showText?LABEL_BOTTOM:LABEL_NONE);
281 firePropertyChange(SHOW_TEXT_CHANGED_PROPERTY, oldValue, showText);
282 }
283
284
285
286
287
288 public boolean isOpaque() {
289 return true;
290 }
291
292
293
294
295
296 public Color getForeground() {
297 return super.getForeground();
298 }
299
300
301
302
303
304 public void setForeground(Color c) {
305 super.setForeground(c);
306 repaint();
307 }
308
309
310
311
312
313
314
315
316 public Color getBackground() {
317 return super.getBackground();
318 }
319
320
321
322
323
324
325
326
327 public void setBackground(Color c) {
328 super.setBackground(c);
329 repaint();
330 }
331
332
333
334
335
336
337
338
339 public Color getBarcodeBackground() {
340 return barcodeBackground;
341 }
342
343
344
345
346
347
348
349
350 public void setBarcodeBackground(Color barcodeBackground) {
351 Color oldValue = this.barcodeBackground;
352 this.barcodeBackground = barcodeBackground;
353 firePropertyChange(BARCODE_BACKGROUND_CHANGED_PROPERTY, oldValue, barcodeBackground);
354 repaint();
355 }
356
357
358
359
360 public javax.swing.border.Border getBorder() {
361 return super.getBorder();
362 }
363
364
365
366
367 public void setBorder(javax.swing.border.Border border) {
368 super.setBorder(border);
369 recalculateSizes();
370 repaint();
371 }
372
373
374
375
376 public Dimension getPreferredSize() {
377 return preferredSize();
378 }
379
380
381
382
383 public void setPreferredSize(Dimension preferredSize) {
384 Dimension oldValue = this.preferredSize;
385 this.preferredSize = preferredSize;
386 firePropertyChange("preferredSize", oldValue, preferredSize);
387 }
388
389
390
391
392
393
394 public Dimension preferredSize() {
395 if (preferredSize != null) {
396 return preferredSize;
397 } else {
398 return new Dimension(getWidth(), getHeight());
399 }
400 }
401
402
403
404
405 public Dimension getMinimumSize() {
406 return minimumSize();
407 }
408
409
410
411
412 public void setMinimumSize(Dimension minimumSize) {
413 Dimension oldValue = this.minimumSize;
414 this.minimumSize = minimumSize;
415 firePropertyChange("minimumSize", oldValue, minimumSize);
416 }
417
418
419
420
421
422
423 public Dimension minimumSize() {
424 if (minimumSize != null) {
425 return minimumSize;
426 } else {
427 return new Dimension(getWidth(), getHeight());
428 }
429 }
430
431
432
433
434 public Font getFont() {
435 return super.getFont();
436 }
437
438
439
440
441 public void setFont(Font font) {
442 super.setFont(font);
443 recalculateSizes();
444 repaint();
445 }
446
447
448
449
450
451 public int getBarcodeHeight() {
452 return barcodeHeight;
453 }
454
455
456
457
458
459 public void setBarcodeHeight(int barcodeHeight) {
460 int oldValue = this.barcodeHeight;
461 this.barcodeHeight = barcodeHeight;
462 firePropertyChange(BARCODE_HEIGHT_CHANGED_PROPERTY, oldValue, barcodeHeight);
463 recalculateSizes();
464 repaint();
465 }
466
467
468
469
470
471 public int getNarrowestBarWidth() {
472 return narrowestBarWidth;
473 }
474
475
476
477
478
479 public void setNarrowestBarWidth(int narrowestBarWidth) {
480 int oldValue = this.narrowestBarWidth;
481 this.narrowestBarWidth = narrowestBarWidth;
482 firePropertyChange(NARROWEST_BAR_WIDTH_CHANGED_PROPERTY, oldValue, narrowestBarWidth);
483 recalculateSizes();
484 repaint();
485 }
486
487
488
489
490 public boolean isFocusTraversable() {
491 return false;
492 }
493
494
495
496
497 protected String paramString() {
498 return code;
499 }
500
501
502
503
504 public String toString() {
505 return code;
506 }
507
508
509
510
511
512 public String getCode() {
513 return code;
514 }
515
516
517
518
519
520 public void setCode(String code) {
521 String oldValue = this.code;
522 this.code = code;
523 firePropertyChange(CODE_CHANGED_PROPERTY, oldValue, code);
524 encode();
525 recalculateSizes();
526 repaint();
527 }
528
529
530
531
532
533 public BarcodeStrategy getCodeType() {
534 return codeType;
535 }
536
537
538
539
540
541 public void setCodeType(BarcodeStrategy codeType) {
542 BarcodeStrategy oldValue = this.codeType;
543 this.codeType = codeType;
544 firePropertyChange(CODE_TYPE_CHANGED_PROPERTY, oldValue, codeType);
545 if (codeType != null && codeType.requiresChecksum() == BarcodeStrategy.MANDATORY_CHECKSUM && checkDigit == false) {
546 setCheckDigit(true);
547
548 } else if (codeType != null && codeType.requiresChecksum() == BarcodeStrategy.NO_CHECKSUM && checkDigit == true) {
549 setCheckDigit(false);
550
551 } else {
552 encode();
553 recalculateSizes();
554 repaint();
555 }
556 }
557
558
559
560
561
562
563
564 public boolean isCheckDigit() {
565 return checkDigit;
566 }
567
568
569
570
571
572
573
574 public void setCheckDigit(boolean checkDigit){
575 if (codeType != null) {
576 if (codeType.requiresChecksum() == BarcodeStrategy.MANDATORY_CHECKSUM && checkDigit == false) {
577
578
579
580 return;
581 } else if (codeType.requiresChecksum() == BarcodeStrategy.NO_CHECKSUM && checkDigit == true) {
582
583
584
585 return;
586 }
587 }
588 boolean oldValue = this.checkDigit;
589 this.checkDigit = checkDigit;
590 firePropertyChange(CHECK_DIGIT_CHANGED_PROPERTY, oldValue, checkDigit);
591 encode();
592 recalculateSizes();
593 repaint();
594 }
595
596
597
598
599 protected void paintComponent(Graphics graphics) {
600 doPaint(graphics, getSize(), getInsets());
601 }
602
603 private void doPaint(Graphics graphics, Dimension d, Insets insets) {
604
605 Graphics2D g = (Graphics2D) graphics;
606
607
608 AffineTransform tran = g.getTransform();
609 Shape oldClip = g.getClip();
610 Color oldColor = g.getColor();
611 Font oldFont = g.getFont();
612
613
614 g.setColor(getBackground());
615 g.fillRect(0, 0, d.width, d.height);
616
617
618
619
620
621
622 Area areaOldClip = null;
623 Rectangle newClip = new Rectangle(insets.left, insets.top,
624 d.width - insets.left - insets.right, d.height - insets.top - insets.bottom);
625 Area areaNewClip = new Area(newClip);
626 if (oldClip != null)
627 {
628 areaOldClip = new Area(oldClip);
629 areaOldClip.intersect(areaNewClip);
630 }
631 else
632 {
633 areaOldClip = areaNewClip;
634 }
635 g.setClip(areaOldClip);
636
637
638 g.rotate(angleDegrees / 180 * Math.PI, d.width / 2.0, d.height / 2.0);
639
640 int barcodeTop = (d.height - (barcodeHeight + labelHeight)) / 2;
641 if(labelPosition!=LABEL_TOP){
642 barcodeTop=(d.height - (barcodeHeight + labelHeight)) / 2;
643 } else{
644 barcodeTop=(d.height - (barcodeHeight + labelHeight)) / 2+labelHeight;
645 }
646
647
648 if (encoded != null) {
649 int x;
650 if(horizontalAlignment==ALIGN_LEFT){
651 x=0;
652 } else if (horizontalAlignment==ALIGN_RIGHT){
653 x=d.width-barcodeWidth;
654 } else {
655 x=(d.width-barcodeWidth)/2;
656 }
657 for(int i = 0; i < encoded.elements.length; i++) {
658 if (encoded.elements[i].getType()==BarcodeElement.TYPE_BAR) {
659
660 g.setColor(getForeground());
661 } else {
662
663 g.setColor(barcodeBackground);
664 }
665 int barWidth = encoded.elements[i].getWidth() * narrowestBarWidth;
666 g.fillRect(x, barcodeTop, barWidth, barcodeHeight);
667 x += barWidth;
668 }
669
670
671 if (labelPosition!=LABEL_NONE) {
672 g.setFont(this.getFont());
673 g.setColor(getForeground());
674 FontMetrics fm = getFontMetrics(g.getFont());
675 int labelTop;
676 if(labelPosition==LABEL_BOTTOM) {
677 labelTop = barcodeTop + barcodeHeight + fm.getAscent();
678 } else {
679 labelTop = barcodeTop - labelHeight + fm.getAscent();
680 }
681 g.drawString(encoded.barcodeLabelText,
682 (d.width - labelWidth) / 2, labelTop);
683 }
684 } else if (!encodeError.equals("")) {
685
686 g.setFont(new Font("Monospaced", Font.PLAIN, 10));
687 FontMetrics fm = getFontMetrics(g.getFont());
688 int labelWidth = fm.stringWidth(encodeError);
689 g.setColor(getBarcodeBackground());
690 g.fillRect((d.width - labelWidth) / 2, barcodeTop,
691 labelWidth, fm.getHeight());
692 g.setColor(getForeground());
693 g.drawString(encodeError,
694 (d.width - labelWidth) / 2,
695 barcodeTop + fm.getAscent()
696 );
697 }
698
699
700 g.setTransform(tran);
701 g.setClip(oldClip);
702 g.setColor(oldColor);
703 g.setFont(oldFont);
704 }
705
706 private void recalculateSizes() {
707
708 if (labelPosition!=LABEL_NONE) {
709 FontMetrics fm = getFontMetrics(getFont());
710 labelHeight = fm.getAscent() + fm.getDescent();
711 } else {
712 labelHeight = 0;
713 }
714
715 Dimension d = calculateControlSize(getRequiredWidth(), barcodeHeight + labelHeight);
716 setPreferredSize(d);
717 setMinimumSize(d);
718 revalidate();
719 }
720
721 private Dimension calculateControlSize(int rectWidth, int rectHeight) {
722
723 Insets insets = getInsets();
724 Dimension d = new Dimension();
725 double angleRadians = angleDegrees / 180.0 * Math.PI;
726
727 d.height = (int) (Math.abs(rectWidth * Math.sin(angleRadians)) + Math.abs(rectHeight * Math.cos(angleRadians)))
728 + insets.top + insets.bottom;
729
730 d.width = (int) (Math.abs(rectWidth * Math.cos(angleRadians)) + Math.abs(rectHeight * Math.sin(angleRadians)))
731 + insets.left + insets.right;
732
733 return d;
734 }
735
736 private int getRequiredWidth() {
737
738 this.barcodeWidth = 0;
739 this.labelWidth = 0;
740
741 if (encoded != null) {
742
743 FontMetrics fm = getFontMetrics(getFont());
744 labelWidth = fm.stringWidth(encoded.barcodeLabelText);
745
746 for(int i = 0; i < encoded.elements.length; i++) {
747 barcodeWidth += encoded.elements[i].getWidth() * narrowestBarWidth;
748 }
749 } else if (!encodeError.equals("")) {
750
751 FontMetrics fm = getFontMetrics(getFont());
752 labelWidth = fm.stringWidth(encodeError);
753 }
754
755 int width = (barcodeWidth > labelWidth) ? barcodeWidth : labelWidth;
756 return width;
757 }
758
759 private void encode() {
760 encodeError = "";
761 if ((codeType != null) && (!code.equals(""))) {
762 try {
763 encoded = codeType.encode(code, checkDigit);
764 } catch (BarcodeException e) {
765 encoded = null;
766 encodeError = e.getMessage();
767 }
768 } else {
769 encoded = null;
770 }
771 }
772
773
774
775
776 public AccessibleContext getAccessibleContext() {
777 return new JComponent.AccessibleJComponent() {
778 public String getAccessibleName() {
779 return "barcode " + code;
780 }
781 public AccessibleRole getAccessibleRole() {
782 return AccessibleRole.LABEL;
783 }
784 };
785 }
786
787
788
789
790
791 public static String getVersion() {
792
793 Class cl=JBarcodeBean.class;
794 URL url = cl.getResource("/META-INF/maven/net.sourceforge.jbarcodebean/jbarcodebean/pom.properties");
795 Properties props=new Properties();
796 try {
797 if(url==null){
798 return "unknown";
799 }
800 InputStream in=url.openStream();
801 props.load(in);
802 in.close();
803 } catch (IOException e) {
804 return "unknown";
805 }
806 return props.getProperty("version");
807 }
808
809
810
811
812
813
814
815
816 public BufferedImage draw(BufferedImage image) {
817 if(image==null) {
818 Dimension pref=getPreferredSize();
819 image=(BufferedImage) createImage(pref.width, pref.height);
820 }
821 encode();
822 recalculateSizes();
823 Graphics2D g = image.createGraphics();
824 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
825 doPaint(g, new Dimension(image.getWidth(), image.getHeight()), new Insets(0, 0, 0, 0));
826 return image;
827 }
828
829
830
831
832
833
834
835
836
837 public int getHorizontalAlignment() {
838 return horizontalAlignment;
839 }
840
841
842
843
844
845
846
847
848
849
850 public void setHorizontalAlignment(int horizontalAlignment) {
851 int oldValue=this.horizontalAlignment;
852 this.horizontalAlignment = horizontalAlignment;
853 firePropertyChange(HORIZONTAL_ALIGNMENR_PROPERTY , oldValue, horizontalAlignment);
854 recalculateSizes();
855 repaint();
856 }
857
858
859
860
861
862
863
864
865
866 public int getLabelPosition() {
867 return labelPosition;
868 }
869
870
871
872
873
874
875
876
877
878 public void setLabelPosition(int labelPosition) {
879 int oldValue=this.labelPosition;
880 this.labelPosition = labelPosition;
881 firePropertyChange(LABEL_POSITION_PROPERTY, oldValue, labelPosition);
882 recalculateSizes();
883 repaint();
884 }
885
886 }
887