S
scooterJava
Gast
Ich habe eine Klasse, die mir sicherstellt, dass ich in einem FlowLayout auch vertikal scrollen kann:
Soweit alles prima. Im Code der Hautpklasse nutze ich sie wie folgt (Auszug):
Auch hier: alles klappt -- bis auf eines. Die Klasse PicturePanel stellt sicher, dass ich in einem Panel ein Hintergrundbild zu sehen bekomme:
Jetzt kommt der Haken: Das Hintergrundbild wird nur zum Teil angezeigt, nämlich nur im oberen Bereich. Ein Aufruf mit setOpaque() hat in einer Vorversion schon geholfen, leider aber nicht, als ich die beiden eigenen Klassen nutzte -- oder ich habe das setOpaque() an die falsche Stelle gesetzt.
Muss ich vielleicht die Methode getPreferredHeight() aus ScrollableFlowPanel ändern? (Hier wird zu einem FlowLayout gecastet). Wenn ja, wie genau muss das aussehen?
Code:
import java.awt.*;
import javax.swing.*;
public class ScrollableFlowPanel
extends JPanel
implements Scrollable
{
// ========================================================================
// FIELDS
// ========================================================================
private static final long serialVersionUID = 1L;
// ========================================================================
// CONSTRUCTORS
// ========================================================================
/* none */
// ========================================================================
// METHODS
// ========================================================================
// ------------------------------------------------------------------------
private int getPreferredHeight()
{
int iPrefWidth = 0;
for( int i = 0, j = getComponentCount(); i < j; i++ )
{
Component oComponent = getComponent( i );
Rectangle oRectangle = oComponent.getBounds();
int iHeight = oRectangle.y + oRectangle.height;
if( iHeight > iPrefWidth )
{
iPrefWidth = iHeight;
}
}
iPrefWidth += ( (FlowLayout)getLayout() ).getVgap();
return iPrefWidth;
}
// ------------------------------------------------------------------------
public Dimension getPreferredScrollableViewportSize()
{
return( super.getPreferredSize() );
}
// ------------------------------------------------------------------------
@Override
public Dimension getPreferredSize()
{
return( new Dimension( getWidth(), getPreferredHeight() ) );
}
// ------------------------------------------------------------------------
public int getScrollableBlockIncrement( final Rectangle oVisibleRect, final int iOrientation, final int iDirection )
{
return( iOrientation == SwingConstants.VERTICAL ? getParent().getHeight() : getParent().getWidth() );
}
// ------------------------------------------------------------------------
public boolean getScrollableTracksViewportHeight()
{
return false;
}
// ------------------------------------------------------------------------
public boolean getScrollableTracksViewportWidth()
{
return true;
}
// ------------------------------------------------------------------------
public int getScrollableUnitIncrement( final Rectangle oVisibleRect, final int iOrientation, final int iDirection )
{
int iHundredth = ( iOrientation == SwingConstants.VERTICAL ? getParent().getHeight() : getParent().getWidth() ) / 100;
return( iHundredth == 0 ? 1 : iHundredth );
}
// ------------------------------------------------------------------------
@Override
public void setBounds( final int iX, final int iY, final int iWidth, final int iHeight )
{
super.setBounds( iX, iY, getParent().getWidth(), iHeight );
}
}
Soweit alles prima. Im Code der Hautpklasse nutze ich sie wie folgt (Auszug):
Code:
// Use PicturePanel with the new method setBackgroundImage() for setting a wallpaper.
PicturePanel panApps = new PicturePanel( new BorderLayout() );
// The image must have this size: Width is the width of the window minus the width of the task pane, height is the height of the window.
panApps.setBackgroundImage( sBackgroundImage );
JLabel labChoose = new JLabel( "blabla", SwingConstants.CENTER );
ScrollableFlowPanel panScrollFlow = new ScrollableFlowPanel();
for( int i = 0; i < sApps.length; i++ )
{
butApps[ i ] = new JButton( sApps[ i ] );
butApps[ i ].setPreferredSize( new Dimension( 150, 50 ) );
butApps[ i ].setText( sApps[ i ] );
butApps[ i ].setFont( new Font( Font.SANS_SERIF, Font.BOLD, 14 ) );
panScrollFlow.add( butApps[ i ] );
}
// Add subpanels to the panels.
JScrollPane panScroll = new JScrollPane( panScrollFlow, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );
panApps.add( labChoose, BorderLayout.NORTH );
panApps.add( panScroll, BorderLayout.CENTER );
Auch hier: alles klappt -- bis auf eines. Die Klasse PicturePanel stellt sicher, dass ich in einem Panel ein Hintergrundbild zu sehen bekomme:
Code:
import java.awt.*;
import javax.swing.JPanel;
public class PicturePanel
extends JPanel
{
// ========================================================================
// FIELDS
// ========================================================================
private static final long serialVersionUID = 1L;
private Image oImage;
// ========================================================================
// CONSTRUCTORS
// ========================================================================
// ------------------------------------------------------------------------
public PicturePanel()
{
super();
}
// ------------------------------------------------------------------------
public PicturePanel( final boolean bIsDoubleBuffered )
{
super( bIsDoubleBuffered );
}
// ------------------------------------------------------------------------
public PicturePanel( final LayoutManager oLayout )
{
super( oLayout );
}
// ------------------------------------------------------------------------
public PicturePanel( final LayoutManager oLayout, final boolean bIsDoubleBuffered )
{
super( oLayout, bIsDoubleBuffered );
}
// ========================================================================
// METHODS
// ========================================================================
// ------------------------------------------------------------------------
@Override
protected void paintComponent( final Graphics oGrahpics )
{
super.paintComponent( oGrahpics );
if( oImage != null )
{
oGrahpics.drawImage( oImage, 0, 0, this );
}
}
// ------------------------------------------------------------------------
/**
* Sets the background image of the panel.
*
* @param sImage - The name of the image. Relative path or none is sufficient. Use PNG as image format for best results.
*/
public void setBackgroundImage( final String sImage )
{
Image oImage = Toolkit.getDefaultToolkit().getImage( sImage );
this.oImage = oImage;
repaint();
}
}
Jetzt kommt der Haken: Das Hintergrundbild wird nur zum Teil angezeigt, nämlich nur im oberen Bereich. Ein Aufruf mit setOpaque() hat in einer Vorversion schon geholfen, leider aber nicht, als ich die beiden eigenen Klassen nutzte -- oder ich habe das setOpaque() an die falsche Stelle gesetzt.
Muss ich vielleicht die Methode getPreferredHeight() aus ScrollableFlowPanel ändern? (Hier wird zu einem FlowLayout gecastet). Wenn ja, wie genau muss das aussehen?