I found this on the internet and wondered if it’s possible to do/use this in Vision…?
I’m not very (not at all ) good in java, so maybe the java gurus here,
in the community, can help…
Summary
// -*- mode:java; encoding:utf-8 -*-
// vim:set fileencoding=utf-8:
// https://ateraimemo.com/Swing/MajorTickOnTrack.html
package example;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.util.Objects;
import javax.swing.*;
public final class MainPanel extends JPanel {
private MainPanel() {
super(new BorderLayout());
JSlider slider = new JSlider();
slider.setSnapToTicks(true);
slider.setMajorTickSpacing(10);
slider.addMouseMotionListener(new MouseAdapter() {
@Override public void mouseDragged(MouseEvent e) {
super.mouseDragged(e);
e.getComponent().repaint();
}
});
UIDefaults d = new UIDefaults();
d.put("Slider.thumbWidth", 24);
d.put("Slider.thumbHeight", 24);
Painter<JSlider> thumbPainter = (g, c, w, h) -> {
g.setPaint(new Color(0x21_98_F6));
g.fillOval(0, 0, 24, 24);
NumberIcon icon = new NumberIcon(slider.getValue());
icon.paintIcon(c, g, 2, 2);
};
d.put("Slider:SliderThumb[Disabled].backgroundPainter", thumbPainter);
d.put("Slider:SliderThumb[Enabled].backgroundPainter", thumbPainter);
d.put("Slider:SliderThumb[Focused+MouseOver].backgroundPainter", thumbPainter);
d.put("Slider:SliderThumb[Focused+Pressed].backgroundPainter", thumbPainter);
d.put("Slider:SliderThumb[Focused].backgroundPainter", thumbPainter);
d.put("Slider:SliderThumb[MouseOver].backgroundPainter", thumbPainter);
d.put("Slider:SliderThumb[Pressed].backgroundPainter", thumbPainter);
d.put("Slider:SliderTrack[Enabled].backgroundPainter", new Painter<JSlider>() {
@Override public void paint(Graphics2D g, JSlider c, int w, int h) {
int arc = 10;
int thumbSize = 24;
int trackHeight = 8;
int tickSize = 4;
int trackWidth = w - thumbSize;
int fillTop = (thumbSize - trackHeight) / 2;
int fillLeft = thumbSize / 2;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(new Color(0xC6_E4_FC));
g.fillRoundRect(fillLeft, fillTop + 2, trackWidth, trackHeight - 4, arc, arc);
int fillBottom = fillTop + trackHeight;
Rectangle r = new Rectangle(fillLeft, fillTop, trackWidth, fillBottom - fillTop);
int fillRight = getXPositionForValue(c, r, c.getValue());
g.setColor(new Color(0x21_98_F6));
g.fillRoundRect(fillLeft, fillTop, fillRight - fillLeft, fillBottom - fillTop, arc, arc);
// Paints the major tick on the track
int value = c.getMinimum();
while (value <= c.getMaximum()) {
int xpt = getXPositionForValue(c, r, value);
g.fillOval(xpt, (int) r.getCenterY() - tickSize / 2, tickSize, tickSize);
// Overflow checking
if (Integer.MAX_VALUE - c.getMajorTickSpacing() < value) {
break;
}
value += c.getMajorTickSpacing();
}
}
// @see javax/swing/plaf/basic/BasicSliderUI#xPositionForValue(int value)
private int getXPositionForValue(JSlider slider, Rectangle trackRect, float value) {
float min = slider.getMinimum();
float max = slider.getMaximum();
float pixelsPerValue = trackRect.width / (max - min);
int trackLeft = trackRect.x;
int trackRight = trackRect.x + trackRect.width - 1;
int pos = trackLeft + Math.round(pixelsPerValue * (value - min));
return Math.max(trackLeft, Math.min(trackRight, pos));
}
});
slider.putClientProperty("Nimbus.Overrides", d);
Box box = Box.createVerticalBox();
box.add(Box.createVerticalStrut(5));
box.add(makeTitledPanel("Default", new JSlider()));
box.add(Box.createVerticalStrut(5));
box.add(makeTitledPanel("Nimbus JSlider.isFilled", slider));
box.add(Box.createVerticalGlue());
add(box);
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
setPreferredSize(new Dimension(320, 240));
}
private static Component makeTitledPanel(String title, Component c) {
JPanel p = new JPanel(new BorderLayout());
p.setBorder(BorderFactory.createTitledBorder(title));
p.add(c);
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(MainPanel::createAndShowGui);
}
private static void createAndShowGui() {
try {
UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
// UIManager.put("JSlider.isFilled", Boolean.TRUE);
// UIManager.put("Slider.paintValue", Boolean.TRUE);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
Toolkit.getDefaultToolkit().beep();
}
JFrame frame = new JFrame("MajorTickOnTrack");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().add(new MainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
class NumberIcon implements Icon {
private final int value;
protected NumberIcon(int value) {
this.value = value;
}
protected Shape getTextShape(Graphics2D g2) {
// Java 12:
// NumberFormat fmt = NumberFormat.getCompactNumberInstance(
// Locale.US, NumberFormat.Style.SHORT);
// String txt = fmt.format(value);
String txt = value > 999 ? "1K" : Objects.toString(value);
AffineTransform at = txt.length() < 3 ? null : AffineTransform.getScaleInstance(.66, 1d);
return new TextLayout(txt, g2.getFont(), g2.getFontRenderContext()).getOutline(at);
}
@Override public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g.create();
g2.translate(x, y);
Shape shape = getTextShape(g2);
Rectangle b = shape.getBounds();
double tx = getIconWidth() / 2d - b.getCenterX();
double ty = getIconHeight() / 2d - b.getCenterY();
AffineTransform toCenterAtf = AffineTransform.getTranslateInstance(tx, ty);
g2.setPaint(Color.WHITE);
g2.fill(toCenterAtf.createTransformedShape(shape));
g2.dispose();
}
@Override public int getIconWidth() {
return 20;
}
@Override public int getIconHeight() {
return 20;
}
}