スクロールバーのある表を真似したいのですが、幅に問題があります。これは非常に単純化されたコードです (ただし、これは完全なアプリケーションであるため、簡単にコンパイルしてすべてを直接見ることができます)。
package view;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import net.miginfocom.layout.AC;
import net.miginfocom.layout.CC;
import net.miginfocom.layout.LC;
import net.miginfocom.swing.MigLayout;
public class AppView
{
private final JFrame main_frame;
public AppView()
{
main_frame = new JFrame();
main_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main_frame.setTitle("Example");
JPanel main_panel = new JPanel() {
private static final long serialVersionUID = 1L;
public Dimension getPreferredSize()
{
return new Dimension(300, 200);
}
};
main_panel.setLayout(new MigLayout("fill"));
JPanel table_panel = new JPanel();
table_panel.setLayout(new MigLayout(new LC(), new AC().gap("0"), new AC().gap("0")));
JScrollPane scroll_pane = new JScrollPane(table_panel);
scroll_pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
int[] width_arr = {20, 20, 20, 20, 20};
for (int i = 0; i < 60; i++) {
for (int j = 0; j < width_arr.length; j++) {
if (j == width_arr.length - 1)
table_panel.add(new JLabel(i + 1 + ", " + (j + 1)), new CC().width(width_arr[j] + "%").wrap());
else
table_panel.add(new JLabel(i + 1 + ", " + (j + 1)), new CC().width(width_arr[j] + "%"));
}
}
main_frame.getContentPane().add(main_panel, BorderLayout.CENTER);
main_panel.add(scroll_pane, new CC().grow());
main_frame.pack();
main_frame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new AppView();
}
});
}
}
ご覧のとおり、 を作成してtable_panel
でラップしscroll_pane
ます。次に、各行に 5 つの JLabel を含む 60 行を追加します。問題は、行の合計幅が 100% になるように各列の幅を指定すると、スクロール要素の幅が急速に増加し始めることです。以下に 2 つのスクリーンショットを示します。1 つは水平スクロールが無効になっている場合、もう 1 つは水平スクロールが有効になっている場合です。
このような動作についての私の提案は、JScrollPane
要素の幅が非常に大きいということですが、この提案は正しくないようです。各列の幅を合計幅が 98% になるように定義すると、すべてが正常に機能するためです。
これらの奇妙なことを理解するのを手伝ってください。前もって感謝します。
[アップデート]
必要なものを達成するために、別のアプローチを使用することにしました。このアプローチは、グリッド機能に基づいています。小さな条件があります - すべての幅の値は 5 の倍数である必要があります。5% を超える精度が必要な状況を想像するのは難しいため、この条件は限定的ではないと思います。まず、20 個の非表示要素を追加します (span()
メソッドをさらに呼び出すため)。
Box empty;
for (int i = 0; i < 20; i++) {
empty = new Box(BoxLayout.X_AXIS);
empty.setVisible(false);
if (i == 19)
table_panel.add(empty, "wrap");
else
table_panel.add(empty);
}
これらの要素がなければ、span()
メソッドは効果がありません。完全なコード サンプルは次のとおりです。
package view;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import net.miginfocom.layout.AC;
import net.miginfocom.layout.CC;
import net.miginfocom.layout.LC;
import net.miginfocom.swing.MigLayout;
public class AppView
{
private final JFrame main_frame;
public AppView()
{
main_frame = new JFrame();
main_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main_frame.setTitle("Example");
JPanel main_panel = new JPanel() {
private static final long serialVersionUID = 1L;
public Dimension getPreferredSize()
{
return new Dimension(300, 200);
}
};
main_panel.setLayout(new MigLayout("fill"));
JPanel table_panel = new JPanel();
table_panel.setLayout(new MigLayout(new LC().fill().debug(1).hideMode(2), new AC().gap("0"), new AC().gap("0")));
JScrollPane scroll_pane = new JScrollPane(table_panel);
scroll_pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
Box empty;
for (int i = 0; i < 20; i++) {
empty = new Box(BoxLayout.X_AXIS);
empty.setVisible(false);
if (i == 19)
table_panel.add(empty, "wrap");
else
table_panel.add(empty);
}
int[] width_arr = {20, 20, 20, 20, 20};
for (int i = 0; i < 60; i++)
for (int j = 0; j < width_arr.length; j++) {
if (j == width_arr.length - 1)
table_panel.add(new JLabel(i + 1 + ", " + (j + 1)), new CC().span(width_arr[j] / 5).wrap());
else
table_panel.add(new JLabel(i + 1 + ", " + (j + 1)), new CC().span(width_arr[j] / 5));
}
main_frame.getContentPane().add(main_panel, BorderLayout.CENTER);
main_panel.add(scroll_pane, new CC().grow());
main_frame.pack();
main_frame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new AppView();
}
});
}
}
これは実際には問題なく動作し、水平スクロールはもう必要ありませんが、非表示のボックスの幅に問題があります - それらの幅は一定ではなく、すべてのボックスで同じではなく、JLabels の幅に依存します。したがって、比率は正しくありません。そして、ここにいくつかのスクリーンショットがあり、それを示しています:
1) 最も単純なケース: 5 つの列、それぞれ 20% の幅で問題なく動作します。
2) より複雑な例: 3 つの列 - 10%、40%、50%。2 列目の幅が 1 列目の 4 倍ではないため、比率が無効です。
さて、次に何をすべきかわかりません。そして、インターネットで何かを見つけようとする試みはすべて無駄でした。