添加AdjustmentListener
...,然后使用JScrollPane
调整ComponentListener#componentResized
的y坐标。
也许另一个选择是覆盖ScrollablePanel#doLayout()
方法:
private static class ScrollablePanel extends JPanel implements Scrollable {
public ScrollablePanel( LayoutManager layout ) {
super( layout );
}
@Override public void doLayout() {
Container p = SwingUtilities.getAncestorOfClass(JViewport.class,this);
if (!(p instanceof JViewport)) {
super.doLayout();
return;
}
JViewport vport = (JViewport) p;
Rectangle vrect = vport.getViewRect();
// search the message bubble that is at the top
Component tgt = null;
for (Component c: getComponents()) {
// not considered if the message bubble height is greater than the viewport height.
if (vrect.contains(c.getLocation())) {
tgt = c;
break;
}
}
// causes this container to lay out its components
super.doLayout();
// keep the message bubble that is at the top
if (tgt != null) {
Point vp = vport.getViewPosition();
vp.y = tgt.getY();
vport.setViewPosition(vp);
}
}
// ...
Main2.java
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JViewport;
import javax.swing.ScrollPaneConstants;
import javax.swing.Scrollable;
import javax.swing.SwingUtilities;
public class Main2
{
public static void main( String[] args ) throws Exception
{
final JPanel layout = new ScrollablePanel( new GridBagLayout() );
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.weightx = 1.0;
for ( int i = 0; i < 20; i++ )
{
layout.add( createMessage( "Marcel: " + i,"Lorem mauris sea aliquam ut justo splendide rhoncus ipsum leo ipsum impedit duo graeci insolens est mea dicunt kasd mus nullam elementum ei tincidunt ullamcorper cetero et aliquyam uonsetetur imperdiet kasd at adipisci nec justo amet duo aliquam at rhoncus nullam splendide facilisi invidunt antiopam duo et splendide amet te vitae partiendo at per inimicus imperdiet rhoncus labore usu vel assentior cursus kasd kasd semper duo vitae mauris his qui aliquyam uonsetetur dicunt eu in habeo takimata definiebas splendide duo kasd qui duo et ullamcorper dicunt Vulputate uonsetetur ullamcorper mauris sea eleifend duo ei definiebas kasd vitae graeci labore inimicus usu vis semper assentior ne odio elementum elementum imperdiet temporibus habeo est ullamcorper semper odio arcu cetero partiendo his eteu iusto corrumpit mus eteu corpora penatibus ut qui pretium te corrumpit his aenean voluptua ipsum his Vulputate usu est insolens assentior arcu et sea aliquyam dicunt inimicus ut nullam ei mauris vis semper duo insolens repudiandae vitae mauris repudiandae definiebas est nec ius labore iusto nec usu dicta ullamcorper in tincidunt mauris voluptua ipsum ut Ut ne dicta aenean eam insolens elementum vitae elementum officiis imperdiet assentior ut ut aliquyam rhoncus vis his invidunt eos est eteu temporibus ei temporibus","20.19.2019",false ),constraints,0 );
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane()
.add( new JScrollPane( layout,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER ) );
frame.setSize( 400,300 );
frame.setVisible( true );
}
private static Component createMessage( String author,String message,String date,boolean left )
{
JPanel messagePanel = new JPanel( new GridBagLayout() )
{
@Override
public Dimension getMinimumSize()
{
//Making sure that the panel can shrink and not only grow.
final Dimension minimumSize = super.getMinimumSize();
minimumSize.width = 0;
return minimumSize;
}
};
final JLabel authorLabel = new JLabel( author );
final JLabel dateLabel = new JLabel( date );
final JTextArea messageText = new JTextArea( message );
messageText.setEditable( false );
messageText.setLineWrap( true );
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = 0;
messagePanel.add( authorLabel,constraints );
constraints.gridx = 1;
constraints.anchor = GridBagConstraints.EAST;
messagePanel.add( dateLabel,constraints );
constraints.gridx = 0;
constraints.gridy = 1;
constraints.gridwidth = 2;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.weightx = 1.0;
messagePanel.add( messageText,constraints );
final Box box = Box.createHorizontalBox();
final Box.Filler filler = new Box.Filler( new Dimension( 20,0 ),new Dimension( 100,new Dimension( 200,0 ) );
box.add( left ? messagePanel : filler );
box.add( Box.createHorizontalGlue() );
box.add( left ? filler : messagePanel );
box.add( Box.createHorizontalGlue() );
return box;
}
private static class ScrollablePanel extends JPanel implements Scrollable
{
public ScrollablePanel( LayoutManager layout )
{
super( layout );
}
@Override public void doLayout() {
Container p = SwingUtilities.getAncestorOfClass(JViewport.class,this);
if (!(p instanceof JViewport)) {
super.doLayout();
return;
}
JViewport vport = (JViewport) p;
Rectangle vrect = vport.getViewRect();
Component tgt = null;
for (Component c: getComponents()) {
if (vrect.contains(c.getLocation())) {
tgt = c;
break;
}
}
super.doLayout();
if (tgt != null) {
Point vp = vport.getViewPosition();
vp.y = tgt.getY();
vport.setViewPosition(vp);
}
}
@Override
public Dimension getPreferredScrollableViewportSize()
{
return getLayout().preferredLayoutSize( this );
}
@Override
public int getScrollableUnitIncrement( final Rectangle visibleRect,final int orientation,final int direction )
{
return 20;
}
@Override
public int getScrollableBlockIncrement( final Rectangle visibleRect,final int direction )
{
return 20;
}
@Override
public boolean getScrollableTracksViewportWidth()
{
return true;
}
@Override
public boolean getScrollableTracksViewportHeight()
{
return false;
}
}
}
本文链接:https://www.f2er.com/3118692.html