我想制作一个动画数字计数器,比如这个:我想能够输入值,并有与动画计数器更新。我可以从google上找到如何在android上实现这一点,但是我找不到任何关于如何在javaswing中实现这一点的信息。我怎样才能在秋千上做出这样的东西?
bvk5enib1#
这不是一个完整的答案,但这是一个滑动jpanel的工作示例。可以修改此代码以在问题中创建显示。下面是完整的可运行示例。
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class SlidingDigitGUI implements Runnable { public static void main(String[] args) { SwingUtilities.invokeLater(new SlidingDigitGUI()); } private SlidingPanel secondPanel; @Override public void run() { JFrame frame = new JFrame("Sliding Digit"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(createSlidingPanel(), BorderLayout.CENTER); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); Animation animation = new Animation(); new Thread(animation).start(); } public JPanel createSlidingPanel() { String[] digitValues = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }; JPanel panel = new JPanel(); panel.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 4, false)); panel.setPreferredSize(new Dimension(300, 100)); Font font = panel.getFont(); Font derivedFont = font.deriveFont(Font.BOLD, 48F); secondPanel = new SlidingPanel(digitValues, derivedFont); secondPanel.setPanelValue("0"); panel.add(secondPanel); return panel; } public class SlidingPanel extends JPanel { private static final long serialVersionUID = 661553022861652947L; private static final int MARGIN = 4; private int imageY; private BufferedImage slidingImage; private Dimension characterDimension; private final Font font; private String currentValue; private final String[] panelValues; public SlidingPanel(String[] panelValues, Font font) { this.panelValues = panelValues; this.font = font; this.characterDimension = calculateFontSize(); this.slidingImage = generateSlidingImage(); this.setPreferredSize(characterDimension); } private Dimension calculateFontSize() { int maxWidth = 0; int maxHeight = 0; FontRenderContext frc = new FontRenderContext(null, true, true); for (String s : panelValues) { Rectangle2D r2D = font.getStringBounds(s, frc); int rWidth = (int) Math.round(r2D.getWidth()); int rHeight = (int) Math.round(r2D.getHeight()); maxWidth = Math.max(maxWidth, rWidth); maxHeight = Math.max(maxHeight, rHeight); } return new Dimension(maxWidth, maxHeight); } private BufferedImage generateSlidingImage() { int height = calculateStringHeight() * (panelValues.length + 1); BufferedImage slidingImage = new BufferedImage(characterDimension.width, height, BufferedImage.TYPE_INT_RGB); Graphics g = slidingImage.getGraphics(); g.setColor(Color.WHITE); g.fillRect(0, 0, characterDimension.width, height); g.setColor(Color.BLACK); g.setFont(font); int y = characterDimension.height - MARGIN; for (String s : panelValues) { g.drawString(s, 0, y); y += calculateStringHeight(); } g.drawString(panelValues[0], 0, y); g.dispose(); return slidingImage; } public void setPanelValue(String value) { int index = getValueIndex(value); this.currentValue = value; this.imageY = calculateStringHeight() * index; repaint(); } public void updatePanelValue(String value) { if (!currentValue.equals(value)) { int index = getValueIndex(value); int finalY = calculateStringHeight() * index; SliderAnimation sliderAnimation = new SliderAnimation(imageY, finalY); new Thread(sliderAnimation).start(); this.currentValue = value; } } private int getValueIndex(String value) { for (int index = 0; index < panelValues.length; index++) { if (value.equals(panelValues[index])) { return index; } } return -1; } private int calculateStringHeight() { return characterDimension.height + MARGIN; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); BufferedImage subImage = slidingImage.getSubimage(0, imageY, characterDimension.width, characterDimension.height); g.drawImage(subImage, 0, 0, this); } public class SliderAnimation implements Runnable { private int originalY; private int finalY; public SliderAnimation(int originalY, int finalY) { this.originalY = originalY; this.finalY = finalY; } @Override public void run() { int differenceY = finalY - originalY; if (finalY == 0) { differenceY = characterDimension.height + MARGIN; } int steps = 10; double difference = (double) differenceY / steps; for (int index = 1; index <= steps; index++) { imageY = (int) Math.round(difference * index + originalY); update(); sleep(120L); } if (finalY == 0) { imageY = 0; update(); } else { imageY = finalY; } } private void update() { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { SlidingPanel.this.repaint(); } }); } private void sleep(long duration) { try { Thread.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class Animation implements Runnable { @Override public void run() { while (true) { update("3"); sleep(2000L); update("8"); sleep(2000L); } } private void update(final String value) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { secondPanel.updatePanelValue(value); } }); } private void sleep(long duration) { try { Thread.sleep(duration); } catch (InterruptedException e) { e.printStackTrace(); } } } }
1条答案
按热度按时间bvk5enib1#
这不是一个完整的答案,但这是一个滑动jpanel的工作示例。可以修改此代码以在问题中创建显示。
下面是完整的可运行示例。