2013-02-22 103 views
-1

enter image description here林想知道是否有人可以幫助我複製下面的截圖。 IM特林顯示計數器,將在20的增量高達100計數將在左側數向上計數1,則保持在增量計數和複製..滾動數字java swing JTextField

enter image description here

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 

等...

+5

[你嘗試過什麼(http://mattgemmell.com/2008/ 12/08/what-you-you-tried /)到目前爲止,以及它不起作用?我會假設你正在嘗試使用[Swing Timer](http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html),對吧? – 2013-02-22 17:10:04

+0

我曾經嘗試過任何一種方式,但它只是一個JTextField,它就是按鍵按鍵。但現在我需要,當它到達一個數字,它增加了下一個..不知道如何甚至奠定它呢.. – Delish 2013-02-22 17:16:34

+2

然後,你可能會過早來到這裏。爲什麼不嘗試並首先嚐試自己想出一個解決方案,只有當你遇到困難時,纔回來嘗試? – 2013-02-22 17:17:19

回答

1

這是一個令人難以置信的基本示例。它的範圍檢查有很大的改進餘地。

enter image description here

直線滾動條是非常簡單的。最後,我使用了與我爲圓形滾動條所做的相同的基本概念,只需創建一個標有所有值的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; 
    } 
} 
+0

非常感謝你,真的幫了我很多很多! – Delish 2013-02-26 14:38:37

+1

我有一堆其他的想法可能會給出更好的結果,但找到時間玩是個問題 – MadProgrammer 2013-02-26 19:04:17

+0

任何想法如何把它放在一個JTextView? (它說截圖上的高度)哈..無論我嘗試似乎只顯示爲邊框:(將編輯原始文章包括截圖.. @MadProgrammer – Delish 2013-02-27 16:28:25

1

您可以使用自定義SliderUI來執行此操作,如圖所示hereJSlider的方向爲VERTICAL。該示例在paintThumb()中調用drawLine(),但您可以使用TextLayout(圖示爲here)來呈現數字。

+1

@BenJi查看GLassPane或JLayer(Java7),僅用於今天的Java GUI JLayer應該是適合這項工作的解決方案,其他任何人都在模擬.... – mKorbel 2013-02-22 22:44:47