我正在处理水平显示移动横幅的applet以及此文本横幅 到达applet窗口的右边界它应该从左边界的开头反转出来,我写下面的类来做工作,问题是当文本横幅到达正确的横幅它崩溃时,applet转到无限循环:
import java.applet.*;
import java.awt.*;
import java.net.*;
import java.io.*;
import javax.swing.*;
/*
<applet code="banner" width=300 height=50>
</applet>
*/
public class TextBanner extends Applet implements Runnable
{
String msg = "Islam Hamdy", temp="";
Thread t = null;
int state;
boolean stopFlag;
int x;
String[] revMsg;
int msgWidth;
boolean isReached;
public void init()
{
setBackground(Color.BLACK);
setForeground(Color.YELLOW);
}
// Start thread
public void start()
{
t = new Thread(this);
stopFlag = false;
t.start();
}
// Entry point for the thread that runs the banner.
public void run()
{
// Display banner
while(true)
{
try
{
repaint();
Thread.sleep(550);
if(stopFlag)
break;
} catch(InterruptedException e) {}
}
}
// Pause the banner.
public void stop()
{
stopFlag = true;
t = null;
}
// Display the banner.
public void paint(Graphics g)
{
String temp2="";
System.out.println("Temp-->"+temp);
int result=x+msgWidth;
FontMetrics fm = g.getFontMetrics();
msgWidth=fm.stringWidth(msg);
g.setFont(new Font("ALGERIAN", Font.PLAIN, 30));
g.drawString(msg, x, 40);
x+=10;
if(x>bounds().width){
x=0;
}
if(result+130>bounds().width){
x=0;
while((x<=bounds().width)){
for(int i=msg.length()-1;i>0;i--){
temp2=Character.toString(msg.charAt(i));
temp=temp2+temp;
// it crashes here
System.out.println("Before draw");
g.drawString(temp, x, 40);
System.out.println("After draw");
repaint();
}
x++;
} // end while
} //end if
}
}
答案 0 :(得分:1)
让我们从...开始......
JApplet
代替Applet
)paint
方法。有很多原因,影响你的主要原因是顶级容器不是双缓冲的。Thread
只是过度杀戮。paint
方法更新动画状态。您已尝试在paint
方法中执行所有动画,这不是paint
的工作方式。将paint
视为电影中的一个框架,由(在您的情况下)线程来确定哪个框架在哪里,事实上,它应该准备应该绘制的内容。repaint
是对paint子系统执行更新的“请求”。重绘经理将决定何时进行实际重绘。这使得执行更新有点棘手...... 更新了示例
public class Reverse extends JApplet {
// Set colors and initialize thread.
public void init() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
setBackground(Color.BLACK);
setForeground(Color.YELLOW);
setLayout(new BorderLayout());
add(new TextPane());
}
});
}
// Start thread
public void start() {
}
// Pause the banner.
public void stop() {
}
public class TextPane extends JPanel {
int state;
boolean stopFlag;
char ch;
int xPos;
String masterMsg = "Islam Hamdy", temp = "";
String msg = masterMsg;
String revMsg;
int msgWidth;
private int direction = 10;
public TextPane() {
setOpaque(false);
setBackground(Color.BLACK);
setForeground(Color.YELLOW);
setFont(new Font("ALGERIAN", Font.PLAIN, 30));
// This only needs to be done one...
StringBuilder sb = new StringBuilder(masterMsg.length());
for (int index = 0; index < masterMsg.length(); index++) {
sb.append(masterMsg.charAt((masterMsg.length() - index) - 1));
}
revMsg = sb.toString();
// Main animation engine. This is responsible for making
// the decisions on where the animation is up to and how
// to react to the edge cases...
Timer timer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
xPos += direction;
FontMetrics fm = getFontMetrics(getFont());
if (xPos > getWidth()) { // this condition fires when the text banner reaches the right banner
direction *= -1;
msg = revMsg;
} else if (xPos < -fm.stringWidth(masterMsg)) {
direction *= -1;
msg = masterMsg;
}
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println(xPos);
FontMetrics fm = g.getFontMetrics();
msgWidth = fm.stringWidth(msg);
g.drawString(msg, xPos, 40);
}
}
}
更新了其他示例
现在,如果你想要更加聪明一点......你可以利用负面缩放过程,这会为你扭转图形......
更新了计时器......
Timer timer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
xPos += direction;
FontMetrics fm = getFontMetrics(getFont());
System.out.println(xPos + "; " + scale);
if (scale > 0 && xPos > getWidth()) { // this condition fires when the text banner reaches the right banner
xPos = -(getWidth() + fm.stringWidth(msg));
scale = -1;
} else if (scale < 0 && xPos >= 0) {
xPos = -fm.stringWidth(msg);
scale = 1;
}
repaint();
}
});
更新的绘画方法......
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.scale(scale, 1);
FontMetrics fm = g2d.getFontMetrics();
msgWidth = fm.stringWidth(msg);
g2d.drawString(msg, xPos, 40);
g2d.dispose();
}
更新为“弹跳”......
这将替换上一个示例中的TextPane
当文本超出右边界时,它会“反转”方向并向左移动,直到超过该边界,再次“反转”......
public class TextPane public class TextPane extends JPanel {
int state;
boolean stopFlag;
char ch;
int xPos;
String msg = "Islam Hamdy";
int msgWidth;
private int direction = 10;
public TextPane() {
setBackground(Color.BLACK);
setForeground(Color.YELLOW);
setFont(new Font("ALGERIAN", Font.PLAIN, 30));
Timer timer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
xPos += direction;
FontMetrics fm = getFontMetrics(getFont());
if (xPos > getWidth()) {
direction *= -1;
} else if (xPos < -fm.stringWidth(msg)) {
direction *= -1;
}
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
FontMetrics fm = g2d.getFontMetrics();
msgWidth = fm.stringWidth(msg);
g2d.drawString(msg, xPos, 40);
g2d.dispose();
}
}
答案 1 :(得分:1)
我现在认为你的意思是'应该跳回到开始',但这会滑回来。但是,除此之外,出于两个原因,我不会考虑这类小程序。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/*
* <applet code="TextBanner" width=600 height=50> </applet>
*/
public class TextBanner extends JApplet {
private TextBannerPanel banner;
// Set colors and initialize thread.
@Override
public void init() {
banner = new TextBannerPanel("Islam Hamdy");
add(banner);
}
// Start animation
@Override
public void start() {
banner.start();
}
// Stop animation
@Override
public void stop() {
banner.stop();
}
}
class TextBannerPanel extends JPanel {
String msg;
int x;
int diff = 5;
Timer timer;
Font font = new Font("ALGERIAN", Font.PLAIN, 30);
public TextBannerPanel() {
new TextBannerPanel("Scrolling Text Banner");
}
public TextBannerPanel(String msg) {
this.msg = msg;
setBackground(Color.BLACK);
setForeground(Color.YELLOW);
ActionListener animate = new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
repaint();
}
};
timer = new Timer(100, animate);
}
// Display the banner.
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(font);
FontMetrics fm = g.getFontMetrics();
int w = (int) fm.getStringBounds(msg, g).getWidth();
g.drawString(msg, x, 40);
x += diff;
diff = x+w > getWidth() ? -5 : diff;
diff = x < 0 ? 5 : diff;
}
public void start() {
timer.start();
}
public void stop() {
timer.stop();
}
}
..应该......反转..
"Islam Hamdy"
另见JArabicInUnicode
:
import javax.swing.*;
import java.awt.*;
/**
* "Peace Be Upon You", "Aslam Alykm' to which the common reply is "Wa alaykum
* as salaam", "And upon you, peace". Information obtained from the document
* http://www.unicode.org/charts/PDF/U0600.pdf Copyright © 1991-2003
* Unicode, Inc. All rights reserved. Arabic is written and read from right to
* left. This source is adapted from the original 'Peace' source written by
* mromarkhan ("Peace be unto you").
*
* @author Omar Khan
* @author Andrew Thompson
* @version 2004-05-31
*/
public class JArabicInUnicode extends JFrame {
/**
* Unicode constant used in this example.
*/
public final static String ALEF = "\u0627",
LAM = "\u0644",
SEEN = "\u0633",
MEEM = "\u0645",
AIN = "\u0639",
YEH = "\u064A",
KAF = "\u0643",
HEH = "\u0647";
/**
* An array of the letters that spell 'Aslam Alykm'.
*/
String text[] = {
ALEF, //a
LAM + SEEN, //s
LAM, //l
ALEF, //a
MEEM, //m
" ",
AIN, //a
LAM, //l
YEH, //y
KAF, //k
MEEM //m
};
/**
* Displays the letters of the phrase 'Aslam Alykm' as well as the words
* spelt out letter by letter.
*/
public JArabicInUnicode() {
super("Peace be upon you");
JTextArea textwod = new JTextArea(7, 10);
textwod.setEditable(false);
textwod.setFont(new Font("null", Font.PLAIN, 22));
String EOL = System.getProperty("line.separator");
// write the phrase to the text area
textwod.append(getCharacters() + EOL);
// now spell it, one letter at a time
for (int ii = 0; ii <= text.length; ii++) {
textwod.append(getCharacters(ii) + EOL);
}
textwod.setCaretPosition(0);
getContentPane().add(
new JScrollPane(textwod,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED),
BorderLayout.CENTER);
pack();
setMinimumSize(getPreferredSize());
try {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
} catch (Exception e) {
} // allows to run under 1.2
}
/**
* Get a string of the entire phrase.
*/
String getCharacters() {
return getCharacters(text.length);
}
/**
* Get a string of the 1st 'num' characters of the phrase.
*/
String getCharacters(int num) {
StringBuffer sb = new StringBuffer();
for (int ii = 1; ii < num; ii++) {
sb.append(text[ii]);
}
return sb.toString();
}
/**
* Instantiate an ArabicInUnicode frame.
*/
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
new JArabicInUnicode().setVisible(true);
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}