MigLayout сбит с толку объектами JTable, содержащимися в объектах JScrollBar - PullRequest
2 голосов
/ 19 марта 2012

Похоже, MigLayout сбивается с толку объектами JTable, содержащимися в объектах JScrollPane. Поскольку представляется вероятным, что использование JTable внутри JScrollPane является обычной идиомой, я подумал, что было бы важно выяснить, почему.

В прилагаемом примере программы создается упрощенная форма, состоящая из 12 строк и 4 столбцов. Все ширины и высоты задаются в процентах. Ряд компонентов добавляется в форму, все по положению ячейки. Некоторые промежутки строк или столбцов. Последний столбец показывает индекс строки ячейки и размер в процентах.

Если программа запускается с аргументом "JLabel", JLabel, содержащийся в JSCrollPane, добавляется в столбец 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

Ответы [ 2 ]

5 голосов
/ 20 марта 2012

Это много ограничений для компонентов (слишком много, чтобы я мог по-настоящему в них разобраться ;-) Так что просто краткий тип ответа:

Разница между меткой и таблицей заключается в том, что в последней реализована прокрутка, в частности ее

Dimension getPreferredScrollableViewportSize();

Это реализовано, чтобы вернуть фиксированное измерение, к сожалению, жестко закодированное в коде инициализации таблицы:

setPreferredScrollableViewportSize(new Dimension(450, 400));

что редко бывает то, что вы хотите.

Эффект на MigLayout заключается в том, что с довольно большой областью (и отступом для фактических строк) переполняется его ячейка настолько, что другие ячейки должны уменьшаться.

Выход в вашем контексте - просто установить prefViewport в null:

clientsTable.setPreferredScrollableViewportSize(null);

( Редактировать обратите внимание, что акцент делается на ваш контекст - разные менеджеры Layout будут сбиты с толку, см. недавний вопрос )

Более общее решение может заключаться в том, чтобы реализовать метод получения чего-то более разумного, например вычислить предпочтение в терминах #of строк (примерно, хотя и не совсем то, что делает 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...
}
0 голосов
/ 21 марта 2012

Интересно, менеджер диспетчера не обрабатывает компонент так, как он мог бы.На общее расстояние между строками компоновки это не повлияет, если прокручиваемый компонент JTable не будет добавлен с термином «spany».Кроме того, немного поиграв с макетом моего приложения, я нашел механизм, в котором все выровнялось нормально.И в моем приложении есть пара других прокручиваемых компонентов JTable в диалоге, который я не использовал в этом примере.Так что иногда менеджер компоновки, кажется, может правильно расставить интервалы.Но сейчас я, вероятно, выйду за рамки стекового потока.(Я планировал отправить вопрос на miglayout.com, но не смог зарегистрироваться на их форумах поддержки.) Спасибо за вашу помощь.

...