невозможно установить ширину столбца после того, как jtable станет видимым

Я сотни раз читал Oracle API, читал бесчисленное количество статей как здесь, так и в других местах, и я все еще не могу изменить размер столбцов после того, как jtable станет видимым.

Как вы можете догадаться, я также пытаюсь установить видимость столбцов с помощью jcheckboxes. Использование addColumn и removeColumn, как отмечалось в других статьях, не возвращает столбцы в их исходное положение. Ранее я использовал дополнительный класс для хранения информации о столбце, например, самого столбца, его идентификатора и исходного индекса. Это стало беспорядком, а также проблема добавления / удаления данных после изменения видимости столбца. Я заметил, что данные не в нужном столбце. В результате ive выбрала установку minWidth, предпочтительной ширины и максимальной ширины столбца.

Теперь к моей проблеме: приведенный ниже код не регулирует ширину столбца, когда для setColumnVisible установлено значение true. По словам Юлиуса Саммнера Миллера, почему это так?

import java.awt.*;
import java.awt.event.*;

import java.util.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;

class run
{
    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                Viewer viewer = new Viewer();

                JFrame jframe = new JFrame();
                jframe.add(viewer);
                jframe.createBufferStrategy(1); // required for dual monitor issues
                jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                jframe.setLocation(50,100);
                jframe.pack();
                jframe.setVisible(true);
            }
        });
    }
}

class Viewer extends JPanel
{
    static final long serialVersionUID = 0;

    DefaultTableModel defaultTableModel;
    JTable jtable;
    JCheckBox jcheckBox[];

    public Viewer()
    {
        this.setLayout(new BorderLayout());

        JPanel jpanel = new JPanel(new BorderLayout());

        String columnNames[] = {"a","b","c","d","e"};

        Object tableData[][] = 
        {
            {"a1","b1","c1","d1","e1"},
            {"a2","b2","c2","d2","e2"},
            {"a3","b3","c3","d3","e3"}
        };

        defaultTableModel = new DefaultTableModel(tableData,columnNames);

        jtable = new JTable(defaultTableModel);

        JScrollPane jscrollPane = new JScrollPane(jtable);

        jpanel.add(jscrollPane,BorderLayout.CENTER);

        TableColumnModel tableColumnModel = jtable.getColumnModel();

        int columnCount = tableColumnModel.getColumnCount();

        jcheckBox = new JCheckBox[columnCount];

        JPanel visibility = new JPanel(new GridLayout(1,columnCount));

        for (int column = 0; column < columnCount; column++)
        {
            TableColumn tableColumn = tableColumnModel.getColumn(column);

            String identifier = (String)tableColumn.getIdentifier();

            jcheckBox[column] = new JCheckBox(identifier,true);
            jcheckBox[column].setName(identifier);
            jcheckBox[column].addActionListener(new ColumnListener());

            visibility.add(jcheckBox[column]);
        }

        jpanel.add(visibility,BorderLayout.SOUTH);

        this.add(jpanel,BorderLayout.CENTER);
    }

    public void setColumnVisible(String identifier, boolean setVisible)
    {
        TableColumn tableColumn = jtable.getColumn(identifier);

        int minWidth = 0;
        int preferredWidth = 0;
        int maxWidth = 0;

        if (setVisible)
        {
            minWidth = 100;
            preferredWidth = 100;
            maxWidth = 100;
        }

        tableColumn.setMinWidth(minWidth);
        tableColumn.setPreferredWidth(preferredWidth);
        tableColumn.setMaxWidth(maxWidth);

        //jtable.doLayout(); does not work
        //jtable.validate(); does not work
        //jtable.getTableHeader().resizeAndRepaint(); does not work
    }

    class ColumnListener implements ActionListener
    {
        public void actionPerformed(ActionEvent actionEvent)
        {
            JCheckBox checkBox = (JCheckBox)actionEvent.getSource();

            boolean setVisible = checkBox.isSelected();

            String identifier = checkBox.getName();

            setColumnVisible(identifier,setVisible);
        }
    }
}



Дополнение doLayout (), validate () resizeAndRepaint () не работает, равно как и отключение setAutoResizeMode.

Примечание. Как некоторые из вас, возможно, узнали, изменение размера действительно работает ПОСЛЕ, когда все столбцы скрыты. Однако он все еще не отвечает на мой вопрос о том, почему размеры столбцов не корректируются при вызове setMin, setPreferred и setMax.

Примечание. Я пишу программу просмотра шрифтов, которая может одновременно отображать несколько семейств шрифтов, стилей и размеров. У меня есть jtable, в которой отображаются установленные шрифты (в столбце 1 отображается семейство шрифтов, в столбце 2 отображается алфавит соответствующим шрифтом, а в столбце 3 отображаются цифры (0–9) в соответствующем шрифте.

Будет использоваться предоставленный пример кода ive чтобы отобразить вышеупомянутое, давая пользователю возможность скрыть алфавит или цифры.

У меня также есть 6 jlist, 3 из которых содержат доступные семейства шрифтов, стили и размеры, а остальные 3 содержат выбор пользователя. Я использую другую jtable для отображения пользовательского выбора (выбранное семейство шрифтов column1, стиль шрифта column2, размер шрифта column3, алфавит column4, цифры column5, пунктуация column6 и символы column7.

Пользователю будет разрешено выбирать, какие столбцы являются Однако, как уже упоминалось, когда таблица отображения обновляется, данные находятся не там, где должны быть, то есть пользователь выбирает скрытие столбцов, цифр и символов, а затем выбирает новые шрифты, стили и размер для отображения.


person johnny    schedule 21.09.2014    source источник
comment
@AndrewThompson, я бы хотел, но я не хотел, чтобы люди спрашивали, где вы активируете видимость? или как вы активируете видимость? я не думаю, что код чрезмерен.   -  person johnny    schedule 21.09.2014
comment
@AndrewThompson, я не хочу ввязываться в педантичную войну, если вы не хотите отвечать, пожалуйста, воздержитесь от комментариев.   -  person johnny    schedule 21.09.2014
comment
На сайте, который дает бесплатные советы, как хорошие, так и плохие, вы не можете напрямую контролировать, что люди публикуют в комментариях или ответах, и вы не должны. Все, что каждый из нас может или должен сделать, - это быть благодарным за то, что некоторые люди нашли время и усилия, чтобы рассмотреть нашу проблему, проголосовать за хороший совет, проголосовать против плохого совета, проигнорировать комментарии, которые нам на самом деле наплевать, и сообщать о оскорбительных сообщениях. Фактически, не стесняйтесь игнорировать эти предложения, если хотите.   -  person Hovercraft Full Of Eels    schedule 21.09.2014
comment
И для протокола, я согласен с @Andrew. Я не могу запустить ваш опубликованный код, не создав предварительно сам MCVE, но вы просите о помощи, так разве ответственность за его создание не должна лежать на ваших плечах? Надеюсь, вы скоро получите помощь с MCVE или без него, но с ним вы, вероятно, получите помощь раньше, так что решать вам.   -  person Hovercraft Full Of Eels    schedule 21.09.2014
comment
@HovercraftFullOfEels, я вижу, это станет уродливым без всякой причины. Во-первых, я понятия не имею, что означает MCVE, кроме дословной интерпретации, минимального полного проверяемого примера. Я должен понимать, что это означает размещение setMinWidth, setPreferredWidth и setMaxWidth?   -  person johnny    schedule 21.09.2014
comment
Не нужно делать что-то уродливое, нужно просто делать шаг за шагом. Значение MCVE можно найти в ссылке @Andrew, приведенной в его первом комментарии, или которую я также предоставляю здесь. Пожалуйста, прочтите его, так как даже если он не поможет вам с этим вопросом, он обязательно поможет в будущих вопросах. Процесс изоляции ошибки до ее наименьшего функционального состояния - полезный инструмент отладки, не только для публикации кода здесь, но и для помощи в отладке ваших собственных программ, поскольку он выявляет ошибку.   -  person Hovercraft Full Of Eels    schedule 21.09.2014
comment
Вам действительно не следует устанавливать нулевую ширину, чтобы скрыть столбец. Когда пользователь использует клавиатуру для перехода от ячейки к ячейке, скрытый столбец по-прежнему принимает фокус, хотя у пользователя нет указаний на то, что столбец имеет фокус. Вместо этого вам следует удалить TableColumn из TableColumnModel. Возможно, вместо этого вы можете использовать Диспетчер столбцов таблицы.   -  person camickr    schedule 21.09.2014
comment
@camickr, как я уже отмечал, удаление столбца таблицы не только добавляет сложности (в данном случае меня это не беспокоит), я хочу знать, почему размер моих столбцов не изменяется после явной установки минимального, предпочтительного и максимального значений.   -  person johnny    schedule 21.09.2014
comment
На этом этапе, возможно, функциональность важнее воспринимаемых проблем со сложностью. Но спасибо, что предоставили MCVE. 1+ голосование за это.   -  person Hovercraft Full Of Eels    schedule 21.09.2014
comment
@HovercraftFullOfEels, я использовал addColumn и removeColumn, но, как вы знаете, позиции не сохраняются. Это не проблема. Проблема в том, что когда я скрываю столбец и добавляю данные в таблицу, данные не находятся в правильном столбце. Может помочь, если он проинформирует читателей, что приложение должно делать.   -  person johnny    schedule 21.09.2014
comment
Для примера.   -  person trashgod    schedule 21.09.2014
comment
@trashgod, я уже написал рабочую программу по этой методике. попробуйте добавить и удалить данные из таблицы и дайте мне знать, что происходит ;-) Я фактически удалил все столбцы из модели столбца таблицы, сохранив их в хэш-карте ‹String, ColumnAttributes›, где атрибуты столбца содержали tablecolumn, идентификатор и исходный индекс. после того, как я сохранил обновления, я добавляю их обратно в модель столбца.   -  person johnny    schedule 21.09.2014


Ответы (1)


как я уже отмечал, удаление столбца таблицы не только добавляет сложности

Я согласен, и я дал вам рабочий код, который управляет этой сложностью. Я вижу, вы не пробовали код, хотя его можно добавить в вашу программу с помощью одной строчки кода.

попробуйте добавить и удалить данные из таблицы

Это не проблема. Все, что делает TableColumn, - это отображает данные из TableModel в TableColumn. Когда вы создаете TableColumn, он создается со значением столбца по умолчанию 0. Итак, да, если вы не справитесь с этим должным образом, у вас будет проблема, поэтому я дал вам ссылку на рабочий код.

мой вопрос о том, почему размеры столбцов не регулируются при вызове setMin, setPreferred и setMax.

Ответ заключается в том, что порядок выполнения кода важен. То есть предпочтительный размер должен быть в диапазоне минимального / максимального размеров, поэтому вам нужно установить предпочтительный размер последним:

    tableColumn.setMinWidth(minWidth);
    tableColumn.setMaxWidth(maxWidth);
    tableColumn.setPreferredWidth(preferredWidth);

Редактировать:

Простой пример. Вы можете называть это MCVE или SSCCE.

import java.awt.*;
import javax.swing.table.*;

public class Main
{
    public static void main(String[] args)
    {
        TableColumn tc = new TableColumn();
        tc.setMinWidth(1);
        tc.setMaxWidth(10);
        tc.setPreferredWidth(15);
        System.out.println( tc.getPreferredWidth() );
    }
}

Если это не подтверждает, что API работает правильно, я не знаю, что будет.

person camickr    schedule 21.09.2014
comment
боже, лолололо ... все так просто. Упоминается ли это где-нибудь в API (т.е. приоритет порядка)? Я видел ваш код, и, не пытаясь вас обидеть, setXXXwidth намного проще. столбцы нельзя будет ни настраивать, ни вкладывать. но спасибо за разъяснение того, что сводило меня с ума в течение нескольких дней. - person johnny; 21.09.2014
comment
@johnny Is that mentioned anywhere in the API - да, прочтите setPreferredWidth() метод API. the columns wont be adjustable, nor will they be tabbable - это действительно упрощает это требование, но вы никогда не знаете, что ждет в будущем :) - person camickr; 21.09.2014
comment
в нем не упоминается порядок приоритета вызова, все, что он говорит, это: если предпочтительная ширина превышает минимальную или максимальную ширину, она корректируется до соответствующего предельного значения ... можно было бы резонно предположить, что порядок вызова не имеет значения. - person johnny; 21.09.2014
comment
@johnny, серьезно, ты не можешь предположить, что порядок важен из этого описания? если максимальное значение равно 0 в то время, когда вы устанавливаете предпочтительную ширину, вы не можете установить его на 100, потому что оно будет сброшено обратно на 0. Это означает, что вы должны установить максимальное значение, прежде чем устанавливать предпочтительное значение. Таким образом, можно было бы разумно предположить, что порядок важен, потому что редактирование выполняется в то время, когда вы пытаетесь изменить предпочтительную ширину. Если бы это описание было для getPreferredWidth, я бы согласился с вами, потому что тогда вы могли бы сохранить все 3 значения и вернуть соответствующее предпочтительное значение. - person camickr; 21.09.2014
comment
нет, если у a есть класс, давайте назовем его Width, и у него есть три переменных min, value и max, и если установить max first, value second и, наконец, min last, и если min меньше max, а значение ›min и меньше чем max, значение равно значению, имеет ли значение, когда я вызываю метод, каковы значения? вышесказанное подразумевает, что независимо от установленных вами значений порядок, в котором вы их вызываете, имеет приоритет над фактическими значениями, что является нелепым. - person johnny; 21.09.2014
comment
@johnny, я бы не хотел поддерживать ваш код. Вы не понимаете основную концепцию min / max как границ диапазона. Вы не можете установить значение, если не знаете границ диапазона. В JDK есть и другие примеры, например полоса прокрутки. Еще раз, вы не можете установить полосу прокрутки на значение, превышающее максимальное значение. Это просто не имеет смысла, и код этому препятствует. Или как насчет JSpinner. Опять же, значение всегда должно быть в диапазоне счетчика. Я постарался объяснить основную концепцию и не собираюсь больше тратить время на эту тему. - person camickr; 21.09.2014
comment
Если предпочтительная ширина превышает минимальную или максимальную ширину, она корректируется до соответствующего предельного значения. что я подразумеваю, меньшее значение. например, мин. 1, макс. 10, значение 15 будет изменено на 1. Я не превышал ни одного (мин. = 100, макс. = 100, предпочтительно = 100). Будет ли разница, если я установлю min на 100, max на 500 и предпочитаю 200? конечно, нет. порядок, в котором я их установил, будет, что не имеет смысла. независимо от того, когда я их установил, min будет 100, max будет 500, а предпочтительным будет 200. Я придерживаюсь api, но его не соблюдают. - person johnny; 21.09.2014
comment
Позвольте нам продолжить это обсуждение в чате. - person johnny; 21.09.2014
comment
@johnny, i adhere to the api - вы не придерживаетесь API. В то время, когда вы пытаетесь установить предпочтительный размер на 100, максимальное значение было 0, поэтому предпочтительным было установлено значение 0. which i take to mean, the lower value eg min 1, max 10, value 15 Почему вы так думаете? appropriate предельное значение - 10. Не предполагайте !!! Это очень легко проверить. См. Мою правку, в которой показаны 5 строк кода, необходимые для демонстрации этого. - person camickr; 21.09.2014
comment
@johnny, мне кажется, я понимаю, что твоя проблема связана со словом exceeds. Вы интерпретируете это как большее, что неточно. Это означает, если значение выходит за границы диапазона мин / макс. Когда значение меньше минимального, оно устанавливается на минимум. Когда значение больше максимального, оно устанавливается на максимум. - person camickr; 21.09.2014