2012-04-26 10 views
8

JavaアプリケーションでJScrollPaneを使用すると少し問題があります。JScrollPaneスクロールバーが表示されているときにJPanelを含むサイズ変更

JScrollPaneにはJPanelが含まれています。 このJPanelは、任意の幅のボタン(垂直順序)で動的に更新されます。 JPanelは、幅が自動的に内側のJButtonコンポーネントに調整されます。

垂直スクロールバーが表示されると、JPanelの右側のスペースが取り除かれ、最大のボタンが完全に表示されなくなります。私は、ボタン全体を表示するだけでなく、水平スクロールバーを使用したくありません。

JPanelのサイズを変更する方法はありますか?スクロールバーが表示されたら、ボタンの隣にうまく表示されますか?または、JPanelの横にスクロールバーを表示させる方法はありますか?

ありがとうございます!

EDIT:ここに私の問題のデモがあります。ウィンドウを小さな高さにリサイズすると、右側のボタンのほんの一部が覆われます。

scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 

EDIT: 私はそれがあなたのケースで仕事をしていないかもしれないと思った。ここ

import java.awt.BorderLayout; 
import java.awt.EventQueue; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import java.awt.GridLayout; 

/** 
* @author Dylan Kiss 
*/ 

public class Demo { 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        JFrame myFrame = new JFrame("Demo"); 
        JPanel sideBar = new JPanel(); 
        JPanel centerPanel = new JPanel(); 
        centerPanel.add(new JLabel("This is the center panel.")); 

        JPanel buttonContainer = new JPanel(); 
        JButton myButton = null; 

        for (int i = 0; i < 20; i++) { 
         buttonContainer.setLayout(new GridLayout(20, 1, 0, 0)); 
         myButton = new JButton("This is my button nr. " + i); 
         buttonContainer.add(myButton); 
        } 

        sideBar.setLayout(new BorderLayout(0, 0)); 

        JScrollPane scrollPane = new JScrollPane(buttonContainer); 

        sideBar.add(scrollPane); 

        myFrame.getContentPane().add(sideBar, BorderLayout.WEST); 
        myFrame.getContentPane().add(centerPanel, BorderLayout.CENTER); 

        myFrame.setLocationByPlatform(true); 
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        myFrame.pack(); 
        myFrame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 
} 
+1

あなたがSSCCEを提供してもらえますか? – StanislavL

+0

大きなプロジェクトの一部です。私は問題の簡単なデモを提供しようとします。 – dylan202

+1

@StanislavL新規ユーザーの場合は、[SSCCE](http://sscce.org/)とリンクする方が良いと思います! :) – COD3BOY

答えて

6

は簡単で、きれいではありません、ソリューションです。これは、スクロールの完全な制御を取得するためにスクロールを実装

private class ButtonContainerHost extends JPanel implements Scrollable { 
    private static final long serialVersionUID = 1L; 

    private final JPanel buttonContainer; 

    public ButtonContainerHost(JPanel buttonContainer) { 
     super(new BorderLayout()); 
     this.buttonContainer = buttonContainer; 
     add(buttonContainer); 
    } 

    @Override 
    public Dimension getPreferredScrollableViewportSize() { 
     Dimension preferredSize = buttonContainer.getPreferredSize(); 
     if (getParent() instanceof JViewport) { 
      preferredSize.width += ((JScrollPane) getParent().getParent()).getVerticalScrollBar() 
        .getPreferredSize().width; 
     } 
     return preferredSize; 
    } 

    @Override 
    public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { 
     return orientation == SwingConstants.HORIZONTAL ? Math.max(visibleRect.width * 9/10, 1) 
       : Math.max(visibleRect.height * 9/10, 1); 
    } 

    @Override 
    public boolean getScrollableTracksViewportHeight() { 
     if (getParent() instanceof JViewport) { 
      JViewport viewport = (JViewport) getParent(); 
      return getPreferredSize().height < viewport.getHeight(); 
     } 
     return false; 
    } 

    @Override 
    public boolean getScrollableTracksViewportWidth() { 
     return true; 
    } 

    @Override 
    public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { 
     return orientation == SwingConstants.HORIZONTAL ? Math.max(visibleRect.width/10, 1) 
       : Math.max(visibleRect.height/10, 1); 
    } 
} 

、スペースが利用可能なときにボタンは拡大を保証するために、ビューポートの高さを追跡して派手なトリックを行います。ここでは、定型のかなり多くを持っているものの、よりよい解決策があります垂直スクロールバーの幅を常に好ましい幅に加算します。それは、垂直スクロールバーが表示されているが、とにかくそれが悪く見えるときに拡大することができます。 EXTENTSIZEはの推奨サイズに設定されている。ここ

if (canScroll && (viewSize.height > extentSize.height)) { 
    prefWidth += vsb.getPreferredSize().width; 
} 

scrollPane = new JScrollPane(new ButtonContainerHost(buttonContainer)); 

この回避策があるためjavax.swing.ScrollPaneLayoutで可能なバグが要求されるようですが、私になります。このようにそれを使用しますviewportおよびviewSizeはviewport.getViewSize()に設定されます。これは正しくないと思われますが、AFAIKビューポート内のビューのサイズは、常に望ましいサイズに等しくなければなりません。ビューサイズは、推奨サイズではなく実際のビューポートサイズと比較する必要があります。

+0

私はむしろ、必要に応じてスクロールバーを表示するだけです:/ – dylan202

+0

ありがとう、このかなりの解決策。私の望むように完璧に動作します。 – dylan202

0

JPanelのサイズを変更する必要があるときにsetPreferredSizeを呼び出すことによって、JPanelのサイズを変更できます。

buttonContainer.setPreferredSize(Dimension d); 
2

Is there a way to resize my JPanel when a scrollbar appears, so it 
appears nicely next to my buttons? 

に関するあなたの要求を満たすために簡単な回避策がEmptyBorderの使用である、これは下の画像のように、起こるべき、あなたはあなたのような感じものを達成できるようになる。

SCROLLBAR SETTING

私はこの行の後に以下の書かれたこの行を追加JPanel buttonContainer = new JPanel();

追加した行

buttonContainer.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); 

ここではその追加した行と、あなたのコードです:

import java.awt.BorderLayout; 
import java.awt.EventQueue; 

import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import java.awt.GridLayout; 

/** 
* @author Dylan Kiss 
*/ 

public class Demo 
{ 
    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       try 
       { 
        JFrame myFrame = new JFrame("Demo"); 
        JPanel sideBar = new JPanel(); 
        JPanel centerPanel = new JPanel(); 
        centerPanel.add(new JLabel("This is the center panel.")); 

        JPanel buttonContainer = new JPanel(); 
        buttonContainer.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); 
        JButton myButton = null; 

        for (int i = 0; i < 20; i++) 
        { 
         buttonContainer.setLayout(new GridLayout(20, 1, 0, 0)); 
         myButton = new JButton("This is my button nr. " + i); 
         buttonContainer.add(myButton); 
        } 

        sideBar.setLayout(new BorderLayout(0, 0)); 

        JScrollPane scrollPane = new JScrollPane(buttonContainer);  

        sideBar.add(scrollPane); 

        myFrame.getContentPane().add(sideBar, BorderLayout.WEST); 
        myFrame.getContentPane().add(centerPanel, BorderLayout.CENTER); 

        myFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
        myFrame.pack(); 
        myFrame.setLocationByPlatform(true); 
        myFrame.setVisible(true); 
       } 
       catch (Exception e) 
       { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 
} 
関連する問題