2

JScrollPane オブジェクトに含まれる JTable オブジェクトによって MigLayout が混乱するようです。JScrollPane 内に JTable を持つことは一般的なイディオムのように思われるので、その理由を見つけることが重要だと思いました。

添付のプログラム例では、12 行 4 列からなる簡略化されたフォームが作成されます。すべての幅と高さはパーセンテージで設定されます。多数のコンポーネントがフォームに追加されますが、すべてセルの位置によって行われます。行または列にまたがるものもあります。最後の列には、セル行のインデックスとサイズのパーセンテージが表示されます。

プログラムが引数「JLabel」で開始された場合、JSCrollPane に含まれる JLabel が列 0 に追加され、すべての配置が適切に表示されます。プログラムが引数「JTable」で開始されると、すべての列の行サイズが乱れます。

これはバグですか、それとも機能ですか?

Make:  javac -classpath <path to miglayout> migtest.java
Usage:  java -classpath <path to miglayout> migtest <JTable|JLabel>

注: 以下のコードが難読化されている (タブがない) ように見える場合は、さまざまな貼り付け方法を試しましたが、プレビューが正しく表示されませんでした。それを修正するために私にできることがあれば教えてください。

import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.util.*;
import java.io.*;
import java.text.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.filechooser.*;
import javax.swing.table.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableColumn;
import net.miginfocom.swing.MigLayout;

public class Migtest extends JFrame {
    public final static int appWidth = 1200; // default

    public final static int appHeight = 800; // default

    String[] clientColNames = { "Name", "Address", "Alternate Address" };

    JComponent createClientsPane(int numCols, String arg) {
        if (arg.equals("jtable")) {
            JTable clientsTable = new JTable(1, numCols);
            clientsTable.getTableHeader().setReorderingAllowed(false);
            clientsTable.getSelectionModel().setSelectionMode(
                    ListSelectionModel.SINGLE_SELECTION);
            clientsTable.getSelectionModel().setSelectionInterval(0, 0);
            JScrollPane scrollPane = new JScrollPane(clientsTable);
            return scrollPane;
        } else
            return new JScrollPane(new JLabel("bear tenders"));
    }

    void init(String[] args) {
        JPanel topPanel = null, subpanel = null;
        String arg;
        if (args.length != 1) {
            System.out.println("missing arg - s/b 'JLabel' or 'jTable'");
            System.exit(0);
        }
        arg = args[0].trim().toLowerCase();
        if (!arg.equals("jlabel") && !arg.equals("jtable")) {
            System.out.println("missing arg - s/b 'JLabel' or 'jTable'");
            System.exit(0);
        }
        setSize(appWidth, appHeight);
        topPanel = new JPanel(new MigLayout("fill,debug",
                "[30%][15%][50%][5%]",
                "[5%][7%][5%][10%][7%][7%][7%][7%][6%][7%][2%][30%]"));
        JCheckBox dynamicInstrumentCheckbox = new JCheckBox(
                "Wood Activities Enabled", false);
        topPanel.add(dynamicInstrumentCheckbox, "cell 0 2");
        topPanel.add(new JLabel("BEAR TENDERS"), "cell 0 4, alignx center");
        topPanel.add(createClientsPane(clientColNames.length, arg),
                "cell 0 5, spany 4, grow");
        topPanel.add(new JLabel("BEAR FACTS"), "cell 1 4, alignx center");
        JRadioButton noneButton = new JRadioButton("None");
        topPanel.add(noneButton, "cell 1 5, gapleft 2%");
        JRadioButton rangeButton = new JRadioButton("Fact 1");
        topPanel.add(rangeButton, "cell 1 6, gapleft 2%");
        JRadioButton playbackButton = new JRadioButton("Fact 2");
        topPanel.add(playbackButton, "cell 1 7, gapleft 2%");
        JButton controlsButton = new JButton("Controls =>");
        topPanel.add(controlsButton, "cell 1 8, alignx center");
        topPanel.add(new JLabel("GUMMY BEARS"), "cell 2 1, alignx center");
        topPanel.add(new JLabel("(gummy bears)"), "cell 2 2, spany 4, grow");
        topPanel.add(new JLabel("CHICAGO BEARS"), "cell 2 6, alignx center");
        topPanel.add(new JLabel("(chicago bears)"), "cell 2 7, spany 3, grow");
        topPanel.add(new JLabel("LOG"), "cell 0 10, alignx left");
        JButton clearLogButton = new JButton("Clear Log");
        topPanel.add(clearLogButton, "cell 2 10, alignx right");
        topPanel.add(new JLabel("(log pane)"), "cell 0 11, spanx 3, grow");
        topPanel.add(new JLabel("0-5%"), "cell 3 0, grow");
        topPanel.add(new JLabel("1-7%"), "cell 3 1, grow");
        topPanel.add(new JLabel("2-5%"), "cell 3 2, grow");
        topPanel.add(new JLabel("3-10%"), "cell 3 3, grow");
        topPanel.add(new JLabel("4-7%"), "cell 3 4, grow");
        topPanel.add(new JLabel("5-7%"), "cell 3 5, grow");
        topPanel.add(new JLabel("6-7%"), "cell 3 6, grow");
        topPanel.add(new JLabel("7-7%"), "cell 3 7, grow");
        topPanel.add(new JLabel("8-6%"), "cell 3 8, grow");
        topPanel.add(new JLabel("9-7%"), "cell 3 9, grow");
        topPanel.add(new JLabel("10-2%"), "cell 3 10, grow");
        topPanel.add(new JLabel("11-30%"), "cell 3 11, grow");
        setContentPane(topPanel);
    }

    public static void main(String[] args) {
        try {
            Migtest thisTest = new Migtest();
            thisText.init(args);
//            thisTest.init(new String[] {"jLabel"});
//            thisTest.init(new String[] {"jTable"});

            // center app window
            GraphicsConfiguration gc = thisTest.getGraphicsConfiguration();
            Rectangle bounds = gc.getBounds();
            thisTest.setLocation(
                    (int) ((bounds.width - thisTest.appWidth) / 2),
                    (int) ((bounds.height - thisTest.appHeight) / 2));
            thisTest.setVisible(true);
        } catch (Exception e) {
            System.out.println("runTest caught exception:  " + e.getMessage());
            e.printStackTrace();
        }
    }
} // class test
4

2 に答える 2

5

それは多くのコンポーネントの制約です(私が実際にそれらを掘り下げるには多すぎます;-)したがって、大雑把なタイプの答えです:

ラベルとテーブルの違いは、後者がスクロール可能、特にその

Dimension getPreferredScrollableViewportSize();

これは固定次元を返すように実装されていますが、残念ながらテーブルの初期化コードでハードコーディングされています。

setPreferredScrollableViewportSize(new Dimension(450, 400));

これはめったにあなたが望むものではありません。

MigLayout への影響は、かなり大きな領域 (および実際の行のインデント) でセルがオーバーフローしすぎて、他のセルが縮小しなければならないことです。

あなたのコンテキストでの方法は、単純に prefViewport を null に設定することです:

clientsTable.setPreferredScrollableViewportSize(null);

(コンテキストに重点が置かれていることに注意してください- 異なる LayoutManagers は混乱します。最近の質問を参照しください)

より一般的な解決策は、ゲッターをより合理的なものに実装することかもしれません.fiは行数の観点から設定を計算します(正確ではありませんが、大まかにJXTableが行うことです)

@Override 
public Dimension getPreferredScrollableViewportSize() {
    if (preferredViewportSize == null) { // hasn't been hard-coded
        if (visibleRowCount < 0) { // a property similar as in JList
             return getPreferredSize(); // use the actual size
        } else {
             Dimension pref = getPreferredSize();
           // calculate height based on # rows that should be visible 
             pref.height = ....
             return pref;
        } 
    } 
    return super.getPr...
}
于 2012-03-20T13:02:33.337 に答える
0

レイアウトマネージャーがコンポーネントを適切に処理していないのではないかと思います。スクロールされた JTable コンポーネントに "spany" 用語が追加されない限り、レイアウト全体の行間隔に悪影響はありません。また、アプリケーションのレイアウトを少し揺すってみると、すべてがうまく整列する配置が見つかりました。また、私のアプリケーションには、例では省略したダイアログ内に、スクロールされる JTable コンポーネントが他にもいくつかあります。そのため、レイアウトマネージャーが適切な間隔を確保できるように見えることがあります。しかし、私はおそらくスタックオーバーフローの範囲を超えています。(質問を miglayout.com に送信する予定でしたが、サポート フォーラムに登録できませんでした。) ご協力ありがとうございます。

于 2012-03-21T14:35:05.883 に答える