-1

在此处输入图像描述我想知道是否有人可以帮我复制下面的屏幕截图。我想显示一个计数器,该计数器将以 20 到 100 的增量计数,将在左侧数字上加 1,然后继续以增量计数并复制..

在此处输入图像描述

eg:000 > 0/0/20      0/1/60
       > 0/0/40      0/1/80
       > 0/0/60      0/2/00
       > 0/0/80      0/2/20
       > 0/1/00      >>>>
       > 0/1/20      0/9/80
       > 0/1/40      1/0/00

ETC...

4

2 回答 2

1

您可以使用此处SliderUI显示的自定义来执行此操作,它具有方向性。该示例调用,但您可以使用(此处说明)来呈现数字。JSliderVERTICALdrawLine ()paintThumb()TextLayout

于 2013-02-22T19:14:09.410 回答
1

这是一个非常基本的例子。它的范围检查有很大的改进空间。

在此处输入图像描述

线性滚动条非常简单。最后,我使用了与圆形滚动条相同的基本概念,简单地创建一个BufferedImage带有所有标记的值,并根据该值计算适当的布局位置。

圆形卷轴需要更长的时间才能实现。最终结果非常基本,问题在于计算欠值和溢出值。

圆形滚动简单创建BufferedImage所有可用值。根据它的显示位置,我们要么在它之前或之后绘制另一个副本,以产生流动的错觉......

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.BoundedRangeModel;
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;

public class Altimiter {

    public static void main(String[] args) {
        new Altimiter();
    }

    public Altimiter() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private AltPane altPane;

        public TestPane() {

            JButton up = new JButton("+");
            JButton down = new JButton("-");

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            add(up, gbc);
            gbc.gridy++;
            add(down, gbc);

            gbc.gridx++;
            gbc.gridy = 0;
            gbc.gridheight = GridBagConstraints.REMAINDER;

            altPane = new AltPane();
            add(altPane, gbc);

            up.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    altPane.setSpeed(25);
                }
            });
            down.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    altPane.setSpeed(-25);
                }
            });

            altPane.setValue(0);

        }
    }

    public class AltPane extends JPanel {

        private LinearScrollerPane major;
        private CircularScrollerPane minor;
        private int altitude = 0;
        private int direction = 0;
        private Timer timer;

        public AltPane() {
            major = new LinearScrollerPane();
            minor = new CircularScrollerPane();
            major.setOpaque(false);
            minor.setOpaque(false);

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.fill = GridBagConstraints.VERTICAL;
            gbc.weighty = 1; 

            add(major, gbc);
            gbc.gridx++;
            add(minor, gbc);
            setBorder(new LineBorder(Color.BLUE));

            timer = new Timer(1000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    altitude += direction;
                    if (altitude < 0) {
                        ((Timer) e.getSource()).stop();
                        altitude = 0;
                    } else if (altitude > 20000) {
                        ((Timer) e.getSource()).stop();
                        altitude = 20000;
                    }
                    System.out.println("value = " + altitude);
                    setValue(altitude);
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.setInitialDelay(0);
        }

        public void setSpeed(int speed) {
            this.direction = speed;
            timer.start();
        }

        public void setValue(int value) {
            int hnds = value / 100;
            int units = value - (hnds * 100);

            if (units == 0) {
                if (hnds > 0 && direction > 0) {
                    units = 100;
                } else if (hnds > 0 && direction < 0) {
                    units = -1;
                } else {
                    units = 0;
                }
            }

            major.setValue(hnds);
            minor.setValue(units);

            invalidate();
            repaint();
        }

        public int getValue() {
            int ths = major.getValue();
            int hnds = minor.getValue();
            return (ths * 100) + hnds;
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            Insets insets = getInsets();
            int width = getWidth() - (insets.left + insets.top);
            int height = getHeight() - (insets.top + insets.bottom);
            g.setColor(new Color(255, 0, 0, 128));
            int centerY = insets.top + (height / 2);
            g.drawLine(insets.left, centerY, insets.left + width, centerY);
        }
    }

    public class CircularScrollerPane extends JPanel {

        private BufferedImage baseView;
        private BoundedRangeModel model;
        private float startValue = 0;
        private float currentValue = 0;
        private float targetValue = 0;
        private int rowCount = 3;
        private Timer timer;
        private long startTime;
        private int runTime = 1000;

        public CircularScrollerPane() {
            setModel(new DefaultBoundedRangeModel(0, 20, 0, 100));

            timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    long now = System.currentTimeMillis();
                    long diff = now - startTime;
                    if (diff >= runTime) {
                        ((Timer) (e.getSource())).stop();
                        diff = runTime;
                    }
                    float progress = (float) diff / (float) runTime;

                    currentValue = calculateProgress(startValue, targetValue, progress);
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(false);
        }

        public int getValue() {
            return getModel().getValue();
        }

        public void setValue(int value) {
            timer.stop();

            BoundedRangeModel model = getModel();
            if (value < model.getMinimum()) {
                value = model.getMaximum() + (value + 1);
                currentValue += model.getMaximum(); // overflow
            } else if (value > model.getMaximum() - model.getExtent()) {
                value = model.getMinimum() + (value - model.getMaximum());
                currentValue -= model.getMaximum(); // underflow
            }
            startValue = currentValue;
            targetValue = value;

            model.setValue(value);

            startTime = System.currentTimeMillis();
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            FontMetrics fm = getFontMetrics(getFont());
            return fm == null ? super.getPreferredSize() : new Dimension(fm.stringWidth("MMM"), fm.getHeight() * getRowCount());
        }

        public void setRowCount(int value) {
            if (value != rowCount) {
                int old = rowCount;
                rowCount = value;
                invalidate();
                repaint();
                firePropertyChange("rowCount", old, rowCount);
            }
        }

        public int getRowCount() {
            return rowCount;
        }

        public void setModel(BoundedRangeModel value) {
            if (value != null) {
                BoundedRangeModel old = model;
                model = value;
                if (model != null) {
                    currentValue = model.getValue();
                    targetValue = model.getValue();
                } else {
                    currentValue = 0;
                    targetValue = 0;
                }
                baseView = null;
                firePropertyChange("model", old, model);
            }
        }

        public BoundedRangeModel getModel() {
            return model;
        }

        @Override
        public void invalidate() {
            super.invalidate();
            baseView = null;
        }

        public float getViewOffSet(float value) {
            Font font = getFont();
            FontMetrics fm = getFontMetrics(font);
            int rowHeight = fm.getHeight();
            int extent = model.getExtent();
            int min = model.getMinimum();
            int max = model.getMaximum();

            int viewRange = max - min;
            int ticks = viewRange / extent;

            float p = value / (float) viewRange;

            return ((rowHeight * ticks) * p) + ((fm.getAscent() + fm.getDescent()) / 2);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            BufferedImage masterView = getMasterView();
            if (masterView != null) {

                Insets insets = getInsets();
                int width = getWidth() - (insets.left + insets.right);
                int height = getHeight() - (insets.top + insets.bottom);
                int centerY = height / 2;
                FontMetrics fm = g.getFontMetrics();

                int yOffset = centerY - (int) getViewOffSet(currentValue);

                g.drawImage(masterView, insets.left, insets.top + yOffset, this);

                // Heading image...
                if (yOffset > 0) {
                    g.drawImage(masterView, insets.left, insets.top + yOffset - masterView.getHeight(), this);
                }
                // Tailing image...
                if (yOffset + masterView.getHeight() < height) {
                    g.drawImage(masterView, insets.left, insets.top + yOffset + masterView.getHeight(), this);
                }
            }
        }

        protected String pad(int value) {
            StringBuilder sb = new StringBuilder(value);
            sb.ensureCapacity(3);
            sb.append(value);
            while (sb.length() < 3) {
                sb.insert(0, "0");
            }
            return sb.toString();
        }

        protected BufferedImage getMasterView() {
            if (baseView == null) {
                Insets insets = getInsets();
                int width = getWidth() - (insets.left + insets.right);
                int height = getHeight() - (insets.top + insets.bottom);

                BoundedRangeModel model = getModel();

                int extent = model.getExtent();
                int min = model.getMinimum();
                int max = model.getMaximum();

                int viewRange = max - min;
                int ticks = viewRange / extent;

                Font font = getFont();
                FontMetrics fm = getFontMetrics(font);
                baseView = new BufferedImage(width, fm.getHeight() * ticks, BufferedImage.TYPE_INT_ARGB);
                Graphics2D g2d = baseView.createGraphics();
                g2d.setFont(font);
                g2d.setColor(Color.BLACK);
                int yPos = 0;
                for (int index = min; index < max; index += extent) {
                    String value = pad(index);
                    g2d.drawString(value, width - fm.stringWidth(value), yPos + fm.getAscent());
                    yPos += fm.getHeight();
                }
            }
            return baseView;
        }
    }

    public class LinearScrollerPane extends JPanel {

        private BufferedImage baseView;
        private BoundedRangeModel model;
        private float startValue = 0;
        private float currentValue = 0;
        private float targetValue = 0;
        private int rowCount = 3;
        private Timer timer;
        private long startTime;
        private int runTime = 1000;

        public LinearScrollerPane() {

            Font font = UIManager.getFont("Label.font");
            setFont(font.deriveFont(Font.BOLD, font.getSize() + 4));
            setModel(new DefaultBoundedRangeModel(0, 0, 0, 20));

            timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    long now = System.currentTimeMillis();
                    long diff = now - startTime;
                    if (diff >= runTime) {
                        ((Timer) (e.getSource())).stop();
                        diff = runTime;
                    }
                    float progress = (float) diff / (float) runTime;

                    currentValue = calculateProgress(startValue, targetValue, progress);
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(false);
        }

        public int getValue() {
            return getModel().getValue();
        }

        public void setValue(int value) {
            timer.stop();

            BoundedRangeModel model = getModel();
            if (value < model.getMinimum()) {
                value = model.getMinimum();
            } else if (value > model.getMaximum() - model.getExtent()) {
                value = model.getMaximum() - model.getExtent();
            }
            startValue = currentValue;
            targetValue = value;

            model.setValue(value);

            startTime = System.currentTimeMillis();
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            FontMetrics fm = getFontMetrics(getFont());
            return fm == null ? super.getPreferredSize() : new Dimension(fm.stringWidth("MM"), fm.getHeight() * getRowCount());
        }

        public void setRowCount(int value) {
            if (value != rowCount) {
                int old = rowCount;
                rowCount = value;
                invalidate();
                repaint();
                firePropertyChange("rowCount", old, rowCount);
            }
        }

        public int getRowCount() {
            return rowCount;
        }

        public void setModel(BoundedRangeModel value) {
            if (value != null) {
                BoundedRangeModel old = model;
                model = value;
                if (model != null) {
                    currentValue = model.getValue();
                    targetValue = model.getValue();
                } else {
                    currentValue = 0;
                    targetValue = 0;
                }
                baseView = null;
                firePropertyChange("model", old, model);
            }
        }

        public BoundedRangeModel getModel() {
            return model;
        }

        @Override
        public void invalidate() {
            super.invalidate();
            baseView = null;
        }

        public float getViewOffSet(float value) {
            Font font = getFont();
            FontMetrics fm = getFontMetrics(font);
            int rowHeight = fm.getHeight();
            int min = model.getMinimum();
            int max = model.getMaximum();

            int viewRange = max - min;
            int ticks = getTicks();

            float p = value / (float) viewRange;

            return ((rowHeight * ticks) * p) + ((fm.getAscent() + fm.getDescent()) / 2);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            BufferedImage masterView = getMasterView();
            if (masterView != null) {

                Insets insets = getInsets();
                int width = getWidth() - (insets.left + insets.right);
                int height = getHeight() - (insets.top + insets.bottom);
                int centerY = height / 2;
                FontMetrics fm = g.getFontMetrics();

                int yOffset = centerY - (int) getViewOffSet(currentValue);

                g.drawImage(masterView, insets.left, insets.top + yOffset, this);
            }
        }

        protected String pad(int value) {
            StringBuilder sb = new StringBuilder(value);
            sb.ensureCapacity(3);
            sb.append(value);
            while (sb.length() < 3) {
                sb.insert(0, "0");
            }
            return sb.toString();
        }

        protected int getTicks() {
            BoundedRangeModel model = getModel();

            int extent = model.getExtent();
            int min = model.getMinimum();
            int max = model.getMaximum();
            int viewRange = max - min;
            int ticks = viewRange;
            if (extent > 0) {
                ticks = viewRange / extent;
            }

            return ticks;
        }

        protected BufferedImage getMasterView() {
            if (baseView == null) {
                Insets insets = getInsets();
                int width = getWidth() - (insets.left + insets.right);
                int height = getHeight() - (insets.top + insets.bottom);

                BoundedRangeModel model = getModel();

                int extent = model.getExtent();
                int min = model.getMinimum();
                int max = model.getMaximum();

                int ticks = getTicks() + 1;

                Font font = getFont();
                FontMetrics fm = getFontMetrics(font);
                baseView = new BufferedImage(width, fm.getHeight() * ticks, BufferedImage.TYPE_INT_ARGB);
                Graphics2D g2d = baseView.createGraphics();
                g2d.setFont(font);
                g2d.setColor(Color.BLACK);
                int yPos = 0;
                for (int index = min; index < max + 1; index += Math.max(1, extent)) {
                    String value = String.valueOf(index);
                    g2d.drawString(value, width - fm.stringWidth(value), yPos + fm.getAscent());
                    yPos += fm.getHeight();
                }
                g2d.dispose();
            }
            return baseView;
        }
    }

    public static float calculateProgress(float startValue, float endValue, double fraction) {
        float value = 0;
        float distance = endValue - startValue;
        value = (float) (distance * fraction);
        value += startValue;
        return value;
    }
}
于 2013-02-26T06:18:34.820 回答