581
584
list.addHighlighter(gradientHighlighter);
582
585
list.toggleSortOrder();
583
586
JXFrame frame = wrapWithScrollingInFrame(table, list,
584
"transparent value relative highlighting");
585
addStatusMessage(frame,
586
"uses the default painter-aware label in renderer");
587
"transparent value relative highlighting (with RelativePH)");
588
// addStatusMessage(frame,
589
// "uses the default painter-aware label in renderer");
587
590
// crude binding to play with options - the factory is incomplete...
588
addStatusComponent(frame, createTransparencyToggle(gradientHighlighter));
591
// addStatusComponent(frame, createTransparencyToggle(gradientHighlighter));
592
//--------- hack around missing size proportional painters
594
public static class RelativePainter<T> extends AbstractLayoutPainter<T> {
596
private Painter<? super T> painter;
597
private double xFactor;
598
private double yFactor;
600
public RelativePainter() {
604
public void setPainter(Painter<? super T> painter) {
605
Object old = getPainter();
606
this.painter = painter;
607
firePropertyChange("painter", old, getPainter());
610
public Painter<? super T> getPainter() {
614
public RelativePainter(Painter<? super T> delegate) {
615
this.painter = delegate;
618
public void setXFactor(double xPercent) {
619
double old = getXFactor();
620
this.xFactor = xPercent;
621
firePropertyChange("xFactor", old, getXFactor());
627
private double getXFactor() {
631
public void setYFactor(double yPercent) {
632
this.yFactor = yPercent;
635
protected void doPaint(Graphics2D g, T object, int width, int height) {
636
if (painter == null) return;
638
if (xFactor != 0.0) {
639
int oldWidth = width;
640
width = (int) (xFactor * width);
641
if (getHorizontalAlignment() == HorizontalAlignment.RIGHT) {
642
g.translate(oldWidth - width, 0);
645
if (yFactor != 0.0) {
646
int oldHeight = height;
647
height = (int) (yFactor * height);
648
if (getVerticalAlignment() == VerticalAlignment.BOTTOM) {
649
g.translate(0, oldHeight - height);
653
painter.paint(g, object, width, height);
657
// -------------------- Value-based transparent gradient highlighter
660
* A Highlighter which applies a value-proportional gradient to PainterAware
661
* rendering components if the value is a Number. The gradient is a simple
662
* red to red.brigther paint. The red can be toggled to
663
* half-transparent.<p>
666
public static class ValueBasedGradientHighlighter extends
668
float maxValue = 100;
670
private boolean yellowTransparent;
672
public ValueBasedGradientHighlighter() {
679
public ValueBasedGradientHighlighter(boolean b) {
680
super(new RelativePainter<JComponent>());
681
setYellowTransparent(b);
685
* Overridden to do nothing if it's not a RelativePainter. We
689
public void setPainter(Painter painter) {
690
if (!(painter instanceof RelativePainter)) return;
691
super.setPainter(painter);
695
public RelativePainter getPainter() {
696
return (RelativePainter) super.getPainter();
700
protected Component doHighlight(Component renderer,
701
ComponentAdapter adapter) {
702
float end = getEndOfGradient((Number) adapter.getValue());
704
renderer.setBackground(Color.RED.darker());
705
renderer.setForeground(Color.WHITE);
706
} else if (end > 0.02) {
707
Painter painter = getPainter(end);
708
((PainterAware) renderer).setPainter(painter);
715
protected boolean canHighlight(Component component,
716
ComponentAdapter adapter) {
717
return (adapter.getValue() instanceof Number) &&
718
super.canHighlight(component, adapter);
722
* @param yellowTransparent
724
public void setYellowTransparent(boolean yellowTransparent) {
725
if (this.yellowTransparent == yellowTransparent) return;
726
this.yellowTransparent = yellowTransparent;
727
getPainter().setPainter(null);
731
public void setHorizontalAlignment(HorizontalAlignment align) {
732
getPainter().setHorizontalAlignment(align);
736
public HorizontalAlignment getHorizontalAlignment() {
737
return getPainter().getHorizontalAlignment();
740
private Painter getPainter(float end) {
741
if (getPainter().getPainter() == null) {
742
Color startColor = getTransparentColor(Color.RED,
743
yellowTransparent ? 125 : 254);
744
Color endColor = getTransparentColor(Color.RED.brighter(), 0);
745
boolean isRightAligned = HorizontalAlignment.RIGHT == getHorizontalAlignment();
746
GradientPaint paint = new GradientPaint(new Point2D.Double(0, 0),
747
isRightAligned ? endColor : startColor,
748
new Point2D.Double(100, 0),
749
isRightAligned ? startColor : endColor);
750
MattePainter painter = new MattePainter(paint);
751
painter.setPaintStretched(true);
752
getPainter().setPainter(painter);
754
getPainter().setXFactor(end);
759
private Color getTransparentColor(Color base, int transparency) {
760
return new Color(base.getRed(), base.getGreen(), base.getBlue(),
764
private float getEndOfGradient(Number number) {
765
float end = number.floatValue() / maxValue;
774
* A Highlighter which applies a value-proportional gradient to PainterAware
775
* rendering components if the value is a Number. The gradient is a simple
776
* red to red.brigther paint. The red can be toggled to
777
* half-transparent.<p>
780
public static class ValueBasedPositionalHighlighter extends
782
float maxValue = 100;
784
public ValueBasedPositionalHighlighter() {
785
super(new RelativePainter<JComponent>());
789
* Overridden to do nothing if it's not a RelativePainter. We
793
public void setPainter(Painter painter) {
794
if (!(painter instanceof RelativePainter)) return;
795
super.setPainter(painter);
799
public RelativePainter getPainter() {
800
return (RelativePainter) super.getPainter();
803
public void setDelegatePainter(Painter painter) {
804
getPainter().setPainter(painter);
808
protected Component doHighlight(Component renderer,
809
ComponentAdapter adapter) {
810
float end = getEndOfGradient((Number) adapter.getValue());
812
renderer.setBackground(Color.RED.darker());
813
renderer.setForeground(Color.WHITE);
814
} else if (end > 0.02) {
815
Painter painter = getPainter(end);
816
((PainterAware) renderer).setPainter(painter);
822
protected boolean canHighlight(Component component,
823
ComponentAdapter adapter) {
824
return (adapter.getValue() instanceof Number) &&
825
super.canHighlight(component, adapter);
828
public void setHorizontalAlignment(HorizontalAlignment align) {
829
getPainter().setHorizontalAlignment(align);
833
public HorizontalAlignment getHorizontalAlignment() {
834
return getPainter().getHorizontalAlignment();
837
private Painter getPainter(float end) {
838
getPainter().setXFactor(end);
841
private float getEndOfGradient(Number number) {
842
float end = number.floatValue() / maxValue;
849
* creates and returns a highlighter with a value-based transparent gradient
850
* if the cell content type is a Number.
854
private ValueBasedGradientHighlighter createTransparentGradientHighlighter() {
855
return new ValueBasedGradientHighlighter();
859
* Creates and returns a checkbox to toggle the gradient's yellow
862
* @param gradientHighlighter
865
private JCheckBox createTransparencyToggle(
866
final ValueBasedGradientHighlighter gradientHighlighter) {
867
ActionContainerFactory factory = new ActionContainerFactory();
868
// toggle opaque optimatization
869
AbstractActionExt toggleTransparent = new AbstractActionExt(
870
"yellow transparent") {
872
public void actionPerformed(ActionEvent e) {
873
gradientHighlighter.setYellowTransparent(isSelected());
877
toggleTransparent.setStateAction();
878
JCheckBox box = new JCheckBox();
879
factory.configureButton(box, toggleTransparent, null);
599
private RelativePainterHighlighter createRelativeGradientHighlighter(
600
HorizontalAlignment right, Number max) {
601
Color startColor = ColorUtil.setAlpha(Color.RED, 130);
602
Color endColor = ColorUtil.setAlpha(Color.RED.brighter(), 0);
603
boolean isRightAligned = HorizontalAlignment.RIGHT == right;
604
GradientPaint paint = new GradientPaint(new Point2D.Double(0, 0),
605
isRightAligned ? endColor : startColor,
606
new Point2D.Double(100, 0),
607
isRightAligned ? startColor : endColor);
608
MattePainter painter = new MattePainter(paint);
609
painter.setPaintStretched(true);
610
RelativePainterHighlighter p = new RelativePainterHighlighter(painter);
611
p.setHorizontalAlignment(right);
612
p.setRelativizer(new NumberRelativizer(max));
883
617
//----------------- Utility