SwingのJScrollPaneについて教えてください

このQ&Aのポイント
  • SwingのJScrollPaneを使用してアプレットを作成中です。パネルのサイズの調整やスクロールの制御を行いたいのですが、うまくいきません。
  • 具体的には、JPanelに時系列データを描画し、常に一番下までスクロールする処理を実装しています。しかし、スライダが正しく動作せず、前回のサイズの最大値に設定されてしまいます。
  • どのように修正すれば正しくスクロールできるようになるのか、分からない状況です。ご教授いただけると助かります。
回答を見る
  • ベストアンサー

Swing のJScrollPane について教えてください

現在、Swing を使用して以下の様な処理のアプレットを作成しています。 ---------------------------------------------------------------  // 画面構成  JPanel p = new JPanel();  JScrollPane sp = new JScrollPane(   p,   ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,   ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED  ); ---------------------------------------------------------------  // パネルサイズの調整  public void resizePanel()  {   p.setPreferredSize(new Dimension(400, 少しづつ増やす));   p.revalidate();  } ---------------------------------------------------------------  // 一番下までスクロールさせる  public void scrollToMaximun()  {   JScrollBar sb = sp.getVerticalScrollBar();   sb.setValue(sb.getMaximum());  } --------------------------------------------------------------- 処理内容は、発生したデータを JPanel に時系列に描画していき、 常に一番下までスクロールさせるという物です。 具体的には、データが発生する度に、描画 & resizePanel() & scrollToMaximun() を行います。 その際、スライダが、一番下までスクロールされず、前回のサイズの 最大値に設定されてしまいます。 根本的なやり方がマズイのか、何がが足りないのかも分からない状態です。 申し訳ございませんが、ご教授頂いたいと思います。

  • Java
  • 回答数2
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
  • aton
  • ベストアンサー率47% (160/334)
回答No.2

 再びatonです。 > スクロールバーの最大値は、JPanelに対しての >  setPreferredSize(); >  revalidate(); > で自動的に変わる物だと思っていました。  これを見て思いついたんですが,resizePanel()メソッドの p.revalidate() を this.revalidate() に変えるとListenerなど使う必要がないかもしれません。ただJScrollPaneはデフフォルトでisValidateRoot()にtrueを返すことになっているので,期待薄ですが。  或いは,resizePanel()メソッドを, public void resizePanel() { p.setPreferredSize(new Dimension(400, 少しづつ増やす)); p.revalidate(); JScrollBar sb = sp.getVerticalScrollBar(); sb.setMaximum(sb.getMaximum() + <pの縦の増加分>) } のような感じにすると,もしかしたらうまくいくようになるかもしれません。

ikazinat
質問者

補足

aton さん丁寧な回答ありがとうございます。 早速試してみた所、  p.revalidate() を this.revalidate() に変えてみましたが結果は同じでした。  sb.setMaximum(sb.getMaximum() + <pの縦の増加分>)  を追加した所、スクロールバーの最大値は確かに更新されました。  しかし、この後で、   sb.setValue(sb.getMaximum());  とやってみましたが、どうしても、前回の最大値の部分にしかスライダが移動しませんでした。  試しに、   sb.setValue(10000);  とパネルより大きい固定値を指定してみましたが、結果は同じでした。 この動作から推測すると、sb.setMaximum() は溜まっているイベントを処理した後 にしか、正しく反映されないのではないか?。 という風に思っています。 JPanel の替わりに JTextArea で試してみたら、キチンと最大値にスライダは移動するので、 何等かの方法はあると思っています。 aton さんに頼ってばかりも申し訳ないので、もう少し、調べてみます。 もし、何がお気づきの点などございましたら、よろしくお願いいたします。

その他の回答 (1)

  • aton
  • ベストアンサー率47% (160/334)
回答No.1

 私もSwing詳しくないんですが,誰も答えないようなので。  APIドキュメントを読むかぎりでは,JScrollBarはBoundedRangeModelを利用してサイズや位置の設定をしています。BoundedRangeModelには「値(value)」「長さ(extent)」「最小値(minimum)」「最大値(maximum)」の4つの基本プロパティがありますが,ikazinatさんの例ではJScrollPaneのAPIドキュメントでいうところの「scrollable client」=JPanelのサイズが変わる(大きくなる)ので,それに合わせてJScrollBarのmaximumの値も変更してやる必要があるのではないかと思います。  JPanelにPropertyChangeListenerかなんかを貼り付けて,JPanelのサイズが変更されたらそのイベントがJScrollPaneあるいはJScrollBarに通知されるようにし,それをもとにJScrollBar#setMaximum()してやったあと,JScrollBar#setValue()してみるとよいのではないでしょうか。  はっきり言って自信はありませんが…。

ikazinat
質問者

補足

aton さん、ご回答ありがとうございます。 スクロールバーの最大値は、JPanelに対しての  setPreferredSize();  revalidate(); で自動的に変わる物だと思っていました。 revalidate() の動作がイマイチ分からなかったので自信は 無かったんですけどね・・・。 早速、リスナーを登録しての方法を試してみます。 また何かありましたら、お願いいたします。

関連するQ&A

  • JScrollPaneのオブジェクトは位置位置

    JScrollPaneについて、質問させて頂きます。 JScrollPaneに、JTextAreaを縦一列に配置したJPanelを追加しようとしたのですが、何故かJScrollPaneに配置すると、JPanel内のJTextAreaの配置が横一列になってしまいます。 つまり、現在は TEST1 TEST2 TEST3 TEST4....(JTextAreaを並べたJPanelです) となっているJScrollPaneを Test1 Test2 Test3 Test4 のように表示したいのです。 大学の授業に絡むコードですので全てを貼付けるとネットから拾ってきたのではと思われてしまうため、全ては貼付けられませんがコードの一部を張りつけさせて頂きます。 まずはJScrollPaneの設定ですが private JScrollPane getScroll() { if (scroll == null) { scroll = new JScrollPane(innerHomeTimeLine); scroll.setPreferredSize(new Dimension(width, height)); scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); scroll.setWheelScrollingEnabled(true); } return scroll; } としてJScrollPaneを作成しています、innerHomeTimeLineはJTextAreaを縦一列に並べたJPanelです。 このJScrollPaneを this.add(getScroll(),BorderLayout.NORTH); でJPanelに追加し、そのJPanel(homeTimeLine)をthis.add(homeTimeLine,BorderLayout.CENTER); でJAppletに追加し、表示しています。 JPanel(innerHomeTimeLine)そのものをJAppletに追加すると縦一列に並んだまま表示出来るのは確認しているので、JScrollPaneの設定の問題だと思うのですが、どうすれば良いのでしょうか.... やり方をご存知の方がいましたら、解答して頂けると助かります、宜しくお願いします。 さすがにこのコードだけでは解答は無理、といったことでしたら、必要な部分を教えて頂ければ、抜き出して追記させて頂きます。

    • ベストアンサー
    • Java
  • JScrollPane上のJTableの再描画

    JPanel上で,以下の初期化関数を作って,データが更新されたときに,この初期化関数を再度呼び出して,テーブルを作り直しています. 描画直後は,正しく表示されるのですが, スクロールバーに触ったり,セルをクリックしたりすると, 初めに作成したテーブルの表示に戻ってしまいます. 何が原因で,どのように対処すれば良いのでしょうか? ご回答いただけますよう,よろしくお願いいたします. public void init_table() { tablemodel1 = new DefaultTableModel(column_names1, text.keyword_num); table1 = new JTable(tablemodel1); scrollt1 = new JScrollPane(table1); add(scrollt1);     以下略 }

    • ベストアンサー
    • Java
  • JScrollPane

    JDialog上に、JScrollPaneにJPanelを付けて、 そこにJTreeを表示しています。 条件を指定して、このJDialogをshowすると、 データをJTreeに表示するのですが、データが多いときは スクロールバーが表示され、必ずスクロールバーの中の スライダ(?)が一番下まで下がっています。 JTreeのルートが見えるように常に右上にしておきたいのですが、 どうすればいいのでしょうか? JTreeでsetSelectionRow(0)とかして、一番上を選択するように してみたのですがうまくいきません。 よろしくお願い致します。

    • ベストアンサー
    • Java
  • Swingについての質問です

    Swingについての質問です  まだJava初心者です^^。とんでもない質問でしたらすいません。  Swingの中の、JFrameを使って、ある図形を描画するという場面です。描画はできたのですが、コンピュータの画面から図形がはみ出してしまって、全体を見る事ができません。そこで、スクロールバーを表示したいと思っているのですが、その方法はどうすれば良いのでしょうか?  下に、普段私が使っている、一本の線を描画するサンプルを書いておきます。 import java.awt.*; import javax.swing.*; public class Sample extend JPanel { public static void main(String[] args){ JFrame frame = new JFrame("Sample"); TestFrame tf = new TestFrame(); frame.add(tf); frame.getComponents().add(tf); frame.setSize(120, 120); //ウインドウサイズを120×120に指定 frame.setBackground(Color.WHITE); frame.setVisible(true); } } class TestFrame extends JPanel{ void paintComponent(Graphics g){ g.drawLine(10, 10, 100, 100); //(10, 10)から(100, 100)に線を描画 } }  もちろんこの場合はスクロールバーは必要ないですが、このような場合でもウインドウサイズを50×50のような小さいサイズにしてしまったときだけスクロールバーが現れるようにできたらもっと嬉しいです。  回答宜しくお願いします。

    • ベストアンサー
    • Java
  • JPaneの大きさ変更について

    JPaneに絵をかいて、画面に表示するプログラムを作ろうと思ったんですが、拡大・縮小の機能を入れようとしたところ、JPanelの大きさのせいなのかJScrollPaneのスクロールバーが最後の絵の部分まで行きませんでした。 そこで、JPaneの大きさを絵の大きさに合わせて変更するようにしようと思ったのですが、してみたところエラーが出てきてわからなくなってしまいました。 誰か対処法を教えてください。プログラムは下に貼っときます。 ---------------------------------- public class Hyou extends JFrame { public Hyou() { // タイトルを設定 setTitle(""); // メインパネルを作成してフレームに追加 MainPanel panel = new MainPanel(); JScrollPane spanel = new JScrollPane(panel,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); Container contentPane = getContentPane(); contentPane.add(spanel); pack(); } } class MainPanel extends JPanel implements MouseListener,ActionListener { static int WIDTH = l * 100 + (k2 * 2); static int HEIGHT = h * 100 + (k1 * 2); setPreferredSize(new Dimension(WIDTH, HEIGHT)); JButton bt3 = new JButton("拡大"); bt3.addActionListener(this); bt3.setActionCommand("big"); bt3.setBounds(new Rectangle(160,20,50,30)); this.add(bt3); } //大きさ変更 void chenge_size(){ MainPanel.setBounds(new Dimension(WIDTH,HEIGHT)); } public void actionPerformed(ActionEvent e){ String command_name = e.getActionCommand(); if(command_name.equals("big")==true){ WIDTH *= 2; repaint(); chenge_size(); } } }

    • ベストアンサー
    • Java
  • スクロールバー

    Javaを始めたばかりの者です。 すごく基本的な質問をさせて頂きます。 恥ずかしいのですが、スクロールバーを付けようとしても付けることができませんでした。 以下がそのプログラムですが、どうすればよいか正直わかりません。よければ教えて下さい。 import java.awt.*; import javax.swing.*; public class ScrolTest { public JPanel panel =new JPanel(); public static void main (String[] argv) { JFrame frame =new JFrame("てすとー"); frame.setSize(50000,6000); Scrollbar scrollbar = new Scrollbar(); frame.add(scrollbar, null); scrollbar.setBounds(new Rectangle(220, 15, 15, 180)); frame.show(); } }

  • javaで2パネルにテーブルデーターを表示

    今日は! javaの初心者で、初心者なりに、フレームに2個のパネルを作成し、各パネルに同じ テーブルデーターを表示するコードを作ってみましたが、旨く行きません。 下記の添付コードで、不具合点の改造箇所をお教え頂けますと大変助かります。 //================================== package packageA; import java.awt.BorderLayout; import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; public class JTableTest2 extends JFrame{ public static void main(String[] args){ JTableTest2 test = new JTableTest2("JTableTest2"); test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); test.setVisible(true); } JTableTest2(String name){ setBounds( 0, 0, 300*2, 140*2); setTitle(name); String data[][] = { //テーブルデータを作る {"田辺太郎","89","79","100","100"}, {"山田大助","68","55","72","100"}, {"佐藤恵美","78","69","81","100"} }; //列名の配列 String title[] = {"名前","数学","英語","国語","音楽"}; JTable table = new JTable(data,title); //テーブルデータと列名でテーブルを作る JPanel p1 = new JPanel(); JPanel p2 = new JPanel(); JScrollPane sp = new JScrollPane(table); sp.setPreferredSize(new Dimension(250, 80)); p1.add(sp); //JPanelにJScrollPaneを結合する p2.add(sp); //JPanelにJScrollPaneを結合する getContentPane().add(p1, BorderLayout.WEST); getContentPane().add(p2, BorderLayout.EAST); } } 以上、宜しくお願いします。

    • ベストアンサー
    • Java
  • JAVAの正解・誤解判定の宣言が分かりません

    class ListPanel extends JPanel implements ActionListener{ JButton button1; JList list1; String[] data = {"( A )","( B )" ,"( C )" ,"( D )" }; ListPanel() { button1 = new JButton("選択OK"); button1.addActionListener(this); list1 = new JList(data); list1.setFixedCellWidth(100); JScrollPane scroll1 = new JScrollPane(list1); scroll1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); scroll1.setPreferredSize(new Dimension(150,80)); scroll1.setBorder(BorderFactory.createEtchedBorder() ); scroll1.setBorder(BorderFactory.createTitledBorder("選択肢") ); JPanel p1 = new JPanel(); p1.add(scroll1); JPanel p2 = new JPanel(); p2.add(button1); this.add(p1); this.add(p2); } public void actionPerformed(ActionEvent e1) { if (e1.getSource() == button1) { if (list1.getSelectedItem() == ( C ) ) { JOptionPane.showMessageDialog(null, "あなたが選択した解答" , " 正解です!",JOptionPane.INFORMATION_MESSAGE); } else if (list1.getSelectedItem() != ( C ) ){ JOptionPane.showMessageDialog(null, "あなたが選択した解答", "間違いです!解答は( C )です" , JOptionPane.INFORMATION_MESSAGE); list1.getSelectedItem() == ( C ) ) { の宣言が間違っているようです。何卒よろしくお願いいたします。どこが間違っているか指摘していただければ幸いです。どうか、よろしくお願いします。

  • スクロールバーの高さが設定できない。

    下のプログラムでJScrollパネルの矢印部分の大きさが変わるはずなのですが 幅は変わるが高さが変わりません。 JScrollBar scrollBar = new JScrollBar(); JScrollPane scrollPanel = new JScrollPane(); scrollBar.setPreferredSize(new Dimension(40,40)); scrollPanel.setVerticalScrollBar(scrollBar);

  • swingのJframeについて

    JFrameについて質問があるのですが import javax.swing.*; public class JFrameTest extends JFrame{ public static void main(String[] args){ JFrameTest frame = new JFrameTest(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(10, 10, 300, 200); frame.setTitle("タイトル"); frame.setVisible(true); } JFrameTest(){ JPanel p = new JPanel();   Container contentPane = getContentPane(); ContentPane.add(p);   pack(); } } このプログラムと import javax.swing.*; public class JFrameTest{ public static void main(String[] args){ JFrame frame = new JFrame("フレームのタイトル"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds( 10, 10, 300, 200); frame.setVisible(true); JPanel p = new JPanel();   Container contentPane = frame.getContentPane(); frame.ContentPane.add(p);   frame.pack(); } } このプログラムは何が違うのでしょう? やってることはまったく一緒だと思ってたのですが、全然違うみたいです。 上のプログラムの JFrameTest(){ はコンストラクタと呼ばれるものなのでしょうか? しょぼい質問で申し訳ないのですが誰か教えていただけないでしょうか。

    • ベストアンサー
    • Java

専門家に質問してみよう