问题描述
简而言之,我想使用swing来实现这种布局:
In short, I want to achieve this layout using swing:
注意两个主要目标:
JPanels 表现为文本,它们被包裹到窗口的宽度,如果空间不足,它们将被包装到下一个行"JPanels.
JPanels behaves as text, they are wrapped to width of a window,and in case of lack of space, they are wraped to next "lines" ofJPanels.
没有水平滚动,但存在垂直滚动拥有查看窗口中所有可能元素的权限.
There is no horizontal scorll, but vertical scroll is present toprivide access to view all possible elements in window.
Nick Rippe 提供了一个几乎完成的解决方案下面,可以看出此处 作为独立的 Java 程序,其中包含我更新的更随机的最内部文本区域字符串和左对齐.
Nick Rippe provided an almost done solution below, it can be seen here as standalone java program with my updated more-random innermost textarea strings and left aligment.
最后一步是在CPanel中修复textareas的每行顶部对齐:
The last step is to fix each-row top alignment of textareas in CPanel:
((WrapLayout)getLayout()).setAlignOnBaseline(true);
完整的解决方案:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.Border;
public class APanel extends JScrollPane {
int width = 0;
public static String getRandomMultilineText() {
String filler = "";
int words = (int) (Math.random() * 7) + 1;
for ( int w = 0 ; w < words ; w++ ) {
int lettersInWord = (int) (Math.random() * 12) + 1;
for ( int l = 0 ; l < lettersInWord ; l++ ) {
filler += "a";
}
filler += "\n";
}
return filler.trim();
}
public APanel() {
super();
setAlignmentX( LEFT_ALIGNMENT );
setAlignmentY( TOP_ALIGNMENT );
final Box B = Box.createVerticalBox();
B.setAlignmentX( LEFT_ALIGNMENT );
B.setAlignmentY( TOP_ALIGNMENT );
for ( int i = 0 ; i < 4 ; i++ ) {
B.add( new CPanel() {
//Important!!! Make sure the width always fits the screen
public Dimension getPreferredSize() {
Dimension result = super.getPreferredSize();
result.width = width - 20; // 20 is for the scroll bar width
return result;
}
} );
}
setViewportView( B );
//Important!!! Need to invalidate the Scroll pane, othewise it
//doesn't try to lay out when the container is shrunk
addComponentListener( new ComponentAdapter() {
public void componentResized( ComponentEvent ce ) {
width = getWidth();
B.invalidate();
}
} );
}
// nothing really very special in this class - mostly here for demonstration
public static class CPanel extends JPanel {
public CPanel() {
super( new WrapLayout( WrapLayout.LEFT ) );
((WrapLayout)getLayout()).setAlignOnBaseline( true);
setOpaque( true );
setBackground( Color.gray );
setAlignmentY( TOP_ALIGNMENT );
setAlignmentX( LEFT_ALIGNMENT );
int wordGroups = (int) (Math.random() * 14) + 7;
//Adding test data (TextAreas)
for ( int i = 0 ; i < wordGroups ; i++ ) {
JTextArea ta = new JTextArea( getRandomMultilineText() );
ta.setAlignmentY( TOP_ALIGNMENT );
ta.setAlignmentX( LEFT_ALIGNMENT);
add( ta );
}
Border bx = BorderFactory.createTitledBorder( "Lovely container" );
setBorder( bx );
}
}
public static void main( String[] args ) {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( new APanel() );
frame.pack();
frame.setSize( 400 , 300 );
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
}
推荐答案
您的问题是您计算面板 C 的首选尺寸.这个首选尺寸需要被覆盖(对于宽度)并包含默认高度.
Your problem is your calculation of your preferredSize of panel C. This preferred size needs to both be overridden (for the width) and contain the default height.
我已经整理了一个演示,以便您了解如何做到这一点:
I've put together a demonstration so you can see how this would be done:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class APanel extends JScrollPane {
int width = 0;
public APanel(){
super();
final Box B = Box.createVerticalBox();
for(int i = 0; i < 4; i++){
B.add(new CPanel(){
//Important!!! Make sure the width always fits the screen
public Dimension getPreferredSize(){
Dimension result = super.getPreferredSize();
result.width = width - 20; // 20 is for the scroll bar width
return result;
}
});
}
setViewportView(B);
//Important!!! Need to invalidate the Scroll pane, othewise it
//doesn't try to lay out when the container is shrunk
addComponentListener(new ComponentAdapter(){
public void componentResized(ComponentEvent ce){
width = getWidth();
B.invalidate();
}
});
}
// nothing really very special in this class - mostly here for demonstration
public static class CPanel extends JPanel{
//Test Data - not necessary
static StringBuffer fillerString;
static {
fillerString = new StringBuffer();
int i = 0;
for(char c = '0'; c < 'z'; c++){
fillerString.append(c);
if(i++ %10 == 0){
fillerString.append('\n');
}
}
}
public CPanel(){
super(new WrapLayout());
setOpaque(true);
setBackground(Color.gray);
//Adding test data (TextAreas)
for(int i = 0; i < 9; i++){
JTextArea ta = new JTextArea(fillerString.toString());
ta.setAlignmentX(LEFT_ALIGNMENT);
add(ta);
}
setBorder(BorderFactory.createTitledBorder("Lovely container"));
}
}
public static void main(String[] args){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new APanel());
frame.pack();
frame.setSize(400, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
这篇关于Java Swing中类似文本的JPanel包装的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!