我试图制作一个新闻自动收报机类型的东西,其中输入一个字符串,并在JPanel内部文本循环。
我知道它目前每秒大约移动90个像素,并且此字体中每个字符大约有16个像素。所以我要问的是我如何使用这些信息来制作它,以便在计时器运行一段时间后,产生一个新的动画文本,以及在第一个动画文本完全离开屏幕后,如何从中删除它记忆。
这是我到目前为止所做的,代码是从这里大量借用的:Java Animate JLabel,所以如果你看到任何不需要的代码,请告诉我。
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.EnumMap;
import javax.swing.*;
@SuppressWarnings("serial")
public class AnimateExample extends JPanel {
private static final int TIMER_DELAY = 20;
private static final String KEY_DOWN = "key down";
public static final int TRANSLATE_SCALE =2;
private static final Font BG_STRING_FONT = new Font(Font.SANS_SERIF,
Font.BOLD, 32);
private EnumMap<Direction, Boolean> dirMap =
new EnumMap<AnimateExample.Direction, Boolean>(Direction.class);
private BufferedImage image = null;
private int posX = 100;
private int posY = 50;
Timer t;
public AnimateExample() {
for (Direction dir : Direction.values()) {
dirMap.put(dir, Boolean.TRUE);
}
t = new Timer(TIMER_DELAY, new TimerListener());
t.start();
ActionMap actionMap = getActionMap();
for (final Direction dir : Direction.values()) {
actionMap.put(dir.Left + KEY_DOWN, new AbstractAction() {
@Override
public void actionPerformed(ActionEvent arg0) {
dirMap.put(dir, true);
}
});
}
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g.setFont(BG_STRING_FONT);
g.setColor(Color.LIGHT_GRAY);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
String s = "Hi, I'm trying to make a news ticker type thing where a string is entered and inside of a JPanel the text is looped.I know it moves currently at about 90 pixels a second and that there is about 16 pixels per char in this font. So what I am asking is how I can use this information to make it so that after a timer runs for a certain time, a new animated text is spawned, and how after the 1st animated text leaves the screen completely, how to delete it from the memory.";
g.drawString(s, posX, posY);
}
private class TimerListener implements ActionListener {
public void actionPerformed(java.awt.event.ActionEvent e) {
for (Direction dir : Direction.values()) {
if (dirMap.get(dir)) {
posX += dir.getX() * TRANSLATE_SCALE;
posY += dir.getY() * TRANSLATE_SCALE;
}
}
repaint();
if(posX<-500)
{
t.stop();
}
};
}
enum Direction {
Left( KeyEvent.VK_LEFT, -1, 0);
private int keyCode;
private int x;
private int y;
private Direction(int keyCode, int x, int y) {
this.keyCode = keyCode;
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
private static void createAndShowGui() {
AnimateExample mainPanel = new AnimateExample();
JFrame frame = new JFrame("Animate Example");
frame.setUndecorated(true);
frame.setSize(1600, 900);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.add(mainPanel);
mainPanel.setBounds(new Rectangle(1600,400));
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
编辑: 我也在想,也许在一定的时间或距离之后重置X位置,但问题是它需要该区域对于一个屏幕长度是空白的。如果你有一个解决方法,它也会很棒。
答案 0 :(得分:2)
您可以查看Marquee Panel。它使用与大多数滚动器不同的方法。您将实际组件添加到面板,并滚动组件。
这允许您滚动文本或图像。您可以使用带有HTML的标签,以便您可以使用彩色文本等。邮件将继续滚动,直到您手动停止滚动。
目前没有替换滚动消息的自动机制。虽然您可以轻松创建消息的列表或队列。然后,当邮件完成完全滚动时,您只需删除当前邮件并添加新邮件。
以下是您需要更改的MarqueePanel
课程的部分代码:
public void actionPerformed(ActionEvent ae)
{
scrollOffset = scrollOffset + scrollAmount;
int width = super.getPreferredSize().width;
if (scrollOffset > width)
{
scrollOffset = isWrap() ? wrapOffset + scrollAmount : - getSize().width;
// add code here to swap component from the List or Queue
}
repaint();
}
当然,您还需要在类中添加一个方法,以便将组件添加到List或Queue中。
答案 1 :(得分:1)
不要担心字符宽度,因为不同的字体会产生可变的字符宽度。而是使用 private double convertToNumber(String number) {
double d = Double.parseDouble(number);
if (d % 1.0 == 0) {
return Integer.parseInt(number);
} else {
return d;
}
}
来衡量FontMetrics
宽度,并将其确定为String
,这时文本将完全偏离屏幕的左侧。
您可以使用某种xPos <= -stringWidth
来管理文本,根据需要弹出下一个文本。此示例只是将最后一条消息弹出到队列的末尾,因此它将不断重复
Queue