- PR -

パネルに描画した文字列のスクロール方法

1
投稿者投稿内容
ボム
ベテラン
会議室デビュー日: 2003/07/25
投稿数: 61
投稿日時: 2003-07-25 13:43
始めましてCasperと申します、いきなり質問で恐縮なのですが、皆様のお知恵をお貸しください。これから、この会議室に貢献できるようにがんばりたいと思います。よろしくお願いします。

下記は単純にスレッドを使い右から左へ文字列をスクロールさせたロジックです。スレッド開始後2秒後にスクロールが0.5秒単位に行われ、文字列が全てスクロールされたら先頭に戻り同じ事を繰り返します。
|----------------------------------------|
|Stringが←へ移動              
|-----------------------------------------|
/**********************************************
public void run(){
 FontMetrics fontM = this.getFontMetrics(Font);
  int Len = fontM.stringWidth(Title) + 10;
  int movePoint = 0;
  try {
   threadScroll.sleep(2000);
   while (threadScroll != null) {
    threadScroll.sleep(500);
    moveTitleX -= 1;
    if (movePoint > Len) {
     moveTitleX = posiTitleX;
     movePoint = 0;
     repaint();
     threadScroll.sleep(threadSleep);
    } else {
     movePoint = movePoint + 1;
     repaint();
    }
   }
  } catch (InterruptedException ie) {}
 }
/************************************************

上記の場合、文字列を描画する位置をただ-1しているだけなのですが、移動する範囲を指定したいのです。
パネルの長さが100として、10の位置から90の位置までを
描画した文字列がスクロールするという事を行いたいのですがわかりません。もちろん文字列の先頭が10の位置までいったら先頭から消えていくようにしたいのです。全部消えたらまた最初からというぐあいに。
|------------------------------------|
| 10                  90 |
|------------------------------------|
お願いします。
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-07-25 14:59
こんにちは。
以下のように moveTitleX を90に戻せばよろしいかと考えますが、いかがでしょうか?

   threadScroll.sleep(2000);
   while (threadScroll != null) {
    threadScroll.sleep(500);
    moveTitleX -= 1;

if (moveTitleX <= -10) moveTitleX = 90;
↑再描画されない範囲にタイミングよく入るよう終了点を調整する。

    if (movePoint > Len) {

先頭から消えていく状態ですが、repaint() 範囲を限定することに
より実現できると考えます。

repaint (int x, int y, int width, int height)

# ちょっとわかりにくい説明になってしまったので、AWTによる
# 方法を書いてみました。(最小構成ですが)。

コード:

import java.awt.*;

public class sample3{

public static void main (String [] args){
AFrame f = new AFrame ();
f.setSize (200, 200);
f.show ();
}

}

class AFrame extends Frame implements Runnable{

Thread thread;
private int X = 90;

AFrame (){
thread = new Thread (this, "second");
thread.start ();
}

public void paint (Graphics g){
g.drawString ("String", X, 100);
}

public void run (){
boolean j = true;
try{
Thread.sleep (2000);
while (j){
Thread.sleep (500);
--X;
repaint (10, 0, 190, 200);
if (X <= -30) X = 90;
}
}
catch (Exception e){
}
}

}




[ メッセージ編集済み 編集者: Ken-Lab 編集日時 2003-07-25 15:52 ]
ボム
ベテラン
会議室デビュー日: 2003/07/25
投稿数: 61
投稿日時: 2003-07-28 11:32
貴重なお答えありがとうございました。
教えていただいたように、repaint(int x, int y, int width, int height)と
描画位置を指定したのですが先頭は消えません。
下記は私のrepaint()関数です。
オフスクリーンを使ってパネルに絵を張り、その上に文字列を描画しております。
文字列には"Number"と"Title"が有り、"Title"が右から左へと移動します。
並びはNumber、Titleの順番で並んでおります。
しかし現状はTitleが右から左へと移動するためNumberの上をTitleが重なって移動している
状況です。

public void paint(Graphics g) {
 if (offImage == null) { // 起動時
  offImage = this.createImage(sizeAlbumPanelW, sizeAlbumPanelH);
  offGraphics = offImage.getGraphics();
  //パネルイメージを描画
  main_img = im_normal;
  offGraphics.drawImage(main_img, 0, 0, this);
  //オフスクリーン描画
  g.drawImage(offImage, 0, 0, this);
 }
 else { // 復活作業
  //パネルイメージを描画
  offGraphics.drawImage(main_img, 0, 0, this);
  //パネルタイトル描画
  offGraphics.setColor(Color.black);
  offGraphics.setFont(TitleFont);
  offGraphics.drawString(Number, posiNumberX, posiNumberY);
  offGraphics.drawString(Title, moveTitleX, posiTitleY);
  //オフスクリーン描画
  g.drawImage(offImage, 0, 0, this);
 }
}
ocean
ベテラン
会議室デビュー日: 2003/07/06
投稿数: 65
投稿日時: 2003-07-28 11:59
Graphics#setClipで幸せになれます。
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-07-28 14:04
Casper様 >
失礼しました。ocean様の方法が一番早くて確実です。

ocean様 >
フォローありがとうございました。この場合setClipを使わないと
ややこしくなりますね。
すっかり抜けてました。


[ メッセージ編集済み 編集者: Ken-Lab 編集日時 2003-07-28 16:38 ]
ボム
ベテラン
会議室デビュー日: 2003/07/25
投稿数: 61
投稿日時: 2003-07-28 14:45
Ken-Lab様
ocean様
ご意見ありがとうございました。

>Graphics#setClip
を使うとの事ですが、API仕様書を読んでもわかりません。
このメソッドをどのように使用するのでしょうか?
もう少し具体的に教えていただくと助かります。
よろしくお願いします。
未記入
大ベテラン
会議室デビュー日: 2003/06/28
投稿数: 219
投稿日時: 2003-07-28 16:28
Ken-Labです。直接ご提示いただいたソースではなくて申し訳ありませんが
先のレスのソースに当てはめました(例題と捉えていただければ・・・)

コード:
import java.awt.*;

public class sample3{

	public static void main (String [] args){
		AFrame f = new AFrame ();
		f.setSize (200, 200);
		f.show ();
	}

}

class AFrame extends Frame implements Runnable{

	Thread thread;
	int X = 120;

	AFrame (){
		thread = new Thread (this, "second");
		thread.start ();
	}

	public void paint (Graphics g){

		// クリッピングしない
		g.drawString ("No Clip/No Move", 30, 80);

		g.setClip (10, 0, 80, 200);

		// クリッピングする
		g.drawString ("Clip/Move", X, 100);
	}

	public void run (){
		boolean j = true;
		try{
			Thread.sleep (2000);
			while (j){
				Thread.sleep (50);
				--X;
				repaint ();
				if (X <= -30) X = 120;
			}
		}
		catch (Exception e){
		}
	}

}

ボム
ベテラン
会議室デビュー日: 2003/07/25
投稿数: 61
投稿日時: 2003-07-29 17:21
Ken-Lab様、非常に具体的なお答えありがとうございました。
教えていただいた通り
まずメインの下絵を描画し
offGraphics.setClip(0,0,100,30);
offGraphics.drawImage(main_img, 0, 0, this);
その後に文字を描画しました
offGraphics.setClip(36, 10, 150, 16);
offGraphics.drawString(Title, moveTitleX, posiTitleY);

1

スキルアップ/キャリアアップ(JOB@IT)