Redimensionnement de JScrollpane avec du contenu de taille variable

Mon redimensionnable JScrollPane du contenu a une largeur minimale. Si le JScrollPane est plus petit que la largeur, les barres de défilement horizontale apparaît. Si elle est supérieure à cette largeur, la fenêtre d'affichage du contenu doit se développer pour remplir la totalité de la fenêtre d'affichage.

Semble être un concept simple, et j'ai quelque chose qui fonctionne, mais il se sent comme un hack:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
public class SSBTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final Component view = new MyView();
final JScrollPane jScrollPane = new JScrollPane(view);
jScrollPane.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(final ComponentEvent e) {
final Dimension minimumSize = view.getMinimumSize();
final int width = Math.max(minimumSize.width, jScrollPane.getViewport().getWidth());
view.setPreferredSize(new Dimension(width, minimumSize.height));
}
});
showInDialog(jScrollPane);
}
});
}
private static void showInDialog(final JScrollPane jScrollPane) {
final JDialog dialog = new JOptionPane(jScrollPane).createDialog("JScrollPane Resize Test");
dialog.setResizable(true);
dialog.setModal(true);
dialog.setVisible(true);
System.exit(0);
}
private static final class MyView extends JPanel {
@Override
protected void paintComponent(final Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.drawString("Dimensions are " + getSize(), 10, 20);
g.drawRect(0, 0, getMinimumSize().width-1, getMinimumSize().height-1);
g.setColor(Color.BLUE);
g.drawRect(0, 0, getPreferredSize().width-1, getPreferredSize().height-1);
}
@Override
public Dimension getMinimumSize() {
return new Dimension(200, 200);
}
@Override
public Dimension getPreferredSize() {
return super.getPreferredSize();
}
}
}

Le redimensionnement de la boîte de dialogue déclenche la ComponentListener, qui définit explicitement la taille par défaut de la fenêtre d'affichage de la vue, l'élément déclencheur de validation. Cependant, le redimensionnement des causes de nervosité des barres de défilement. Est-il une manière plus propre de faire cela?

EDIT: grâce à camickr pour la ScrollablePanel lien, j'ai modifié ma Composite de classe pour mettre en œuvre de Défilement, et de modifier dynamiquement la valeur de retour de getScrollableTracksViewportWidth().

Lorsque la fenêtre est grande, je reviens true pour getScrollableTracksViewportWidth()en disant à la JScrollPane pour remplir la vue avec mon composant. Lorsque la fenêtre est petite, je reviens falsede sorte que les barres de défilement apparaissent.

import javax.swing.*;
import java.awt.*;
public class SSBTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final Component view = new MyView();
final JScrollPane jScrollPane = new JScrollPane(view);
showInDialog(jScrollPane);
}
});
}
private static void showInDialog(final JScrollPane jScrollPane) {
final JDialog dialog = new JOptionPane(jScrollPane).createDialog("JScrollPane Resize Test");
dialog.setResizable(true);
dialog.setModal(true);
dialog.setVisible(true);
System.exit(0);
}
private static final class MyView extends JPanel implements Scrollable {
@Override
protected void paintComponent(final Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.drawString("MyView: " + getWidth() + "x" + getHeight(), 10, 20);
g.drawRect(0, 0, getMinimumSize().width-1, getMinimumSize().height-1);
g.setColor(Color.BLUE);
g.drawRect(0, 0, getPreferredSize().width-1, getPreferredSize().height-1);
g.drawString("Preferred/Minimum Size", 10, getPreferredSize().height/2);
g.setColor(Color.GREEN);
g.drawLine(0, 0, getWidth(), getHeight());
}
@Override
public Dimension getMinimumSize() {
return new Dimension(200, 200);
}
@Override
public Dimension getPreferredSize() {
return getMinimumSize();
}
public Dimension getPreferredScrollableViewportSize() {
return getPreferredSize();
}
public int getScrollableUnitIncrement(final Rectangle visibleRect, final int orientation, final int direction) {
return 10;
}
public int getScrollableBlockIncrement(final Rectangle visibleRect, final int orientation, final int direction) {
return visibleRect.width;
}
public boolean getScrollableTracksViewportWidth() {
final Container viewport = getParent();
return viewport.getWidth() > getMinimumSize().width;
}
public boolean getScrollableTracksViewportHeight() {
return true;
}
}
}

source d'informationauteur Sam Barnum