JTable, JLabel и его Icon (JLabel нельзя настроить с помощью Icon)? - PullRequest
4 голосов
/ 21 августа 2011

Это лето не настоящее лето, подумал я.Чашка кофе заставляет меня чувствовать это как лето, жесткое (смеется).

У меня есть немного непослушный JTable.О, МОЙ БОГ.Ниже мой JTable, который использует мою собственную настроенную TableModel.Вы могли видеть это по методу getColumnClass (), там ... он был сделан для возврата только как JLabel .И затем я также настраиваю DefaultRenderer .

jtbl_inGameEasy = new javax.swing.JTable();
jtbl_inGameEasy.setFont(new java.awt.Font("squeaky chalk sound", 0, 14)); // NOI18N
jtbl_inGameEasy.setForeground(new java.awt.Color(255, 255, 255));
jtbl_inGameEasy.setModel(new javax.swing.table.DefaultTableModel(
    new Object [][] {

    },
    new String [] {
        "null", "null", "null", "null", "null"
    }
) {
    boolean[] canEdit = new boolean [] {
        false, false, false, false, false
    };

    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return canEdit [columnIndex];
    }
    public Class getColumnClass(int columnIndex) {
        return JLabel.class;
    }
});
jtbl_inGameEasy.setDefaultRenderer(JLabel.class, new JLabelTableRenderer());
jtbl_inGameEasy.setFocusable(false);
jtbl_inGameEasy.setOpaque(false);
jtbl_inGameEasy.setRowHeight(55);
jtbl_inGameEasy.setShowHorizontalLines(false);
jtbl_inGameEasy.setShowVerticalLines(false);
jtbl_inGameEasy.setTableHeader(null);
jtbl_inGameEasy.addMouseListener(new java.awt.event.MouseAdapter() {
    public void mousePressed(java.awt.event.MouseEvent evt) {
        jtbl_inGameEasyMousePressed(evt);
    }
});

А где находится JTableRenderer ?Вот ... это мой пользовательский рендерер ниже ...

public class JLabelTableRenderer extends DefaultTableCellRenderer {

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int column) {

        if (value instanceof JLabel) {
            //This time return only the JLabel without icon
            return (JLabel) value;
        } else {
            return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        }

    }
}

А потом мне нужно положить JLabel внутрь каждой ячейки.Я начинаю добавлять несколько JLabel (s) внутри объекта массива над ячейками JTable , используя этот код;(что не проблема).

DefaultTableModel o_dtb = jtbl_inGameEasy.getModel();
o_dtb.addRow(myArrayCustomizedObjectofJLabel);

Все работает нормально, наверное.Но из-за Моей цели заключается в том, чтобы ---> установить Icon или сделать его невидимым, как только пользователь нажмет на JTable Cells , поэтому я попыталсявыполните мой MouseEvent один раз , нажмите и вызовите эти строки кода;

private void jtbl_inGameEasyMousePressed(java.awt.event.MouseEvent evt) {                                             
        // Checking inGameEasy Table Ans
        javax.swing.JTable source = (javax.swing.JTable) evt.getSource();
        int row = source.rowAtPoint(evt.getPoint());
        int column = source.columnAtPoint(evt.getPoint());

        DefaultTableModel o_dtb = (DefaultTableModel) jtbl_inGameEasy.getModel();
        String s_questAns = "" + Game.getCurrentQuestion().getResult();
        String s_userAns = "" + o_dtb.getValueAt(row, column);

// These two lines below are not Working, why yaa??    

    ((JLabel) o_dtb.getValueAt(row, column)).setVisible(false);
((JLabel) o_dtb.getValueAt(row, column)).setIcon(myIcon);

        if (s_questAns.equals(s_userAns)) {
            Game.correct();
            System.err.println("nice ans!");
        } else {
            jll_txtMiss.setText("Miss : " + Game.wrong());
            System.err.println("nope!");
        }

        nextQuestion();
    }               

И мне кажется, что Помечено (ниже прокомментировал ) код выше не работает.Да, кастуемую JLabel нельзя было изменить ни ее иконкой (изображением), ни ее видимостью.Является ли это Модель причиной всего этого ?Примечание: данные «Мои ячейки» добавляются позже, после того как модель создается по-другому.

1 Ответ

4 голосов
/ 21 августа 2011

Мне кажется, что вы хотите просто оставить все ячейки таблицы пустыми, кроме тех, которые щелкает пользователь, где должен появиться какой-нибудь значок метки, верно?

Если это так, ваша таблицаМодель не должна содержать JLabel экземпляров.JLabel - это визуальный компонент, используемый для графической визуализации некоторых данных.Сами данные не являются JLabel.В вашем случае, я думаю, что это должно быть логическое значение (true при нажатии пользователем, false в противном случае).

Теперь вы можете использовать пользовательский рендерер (хотя по умолчанию для логических значений также может быть в порядке), чтобыпоказать ваши логические.Этот рендер будет подклассом DefaultTableCellRenderer, который сам является подклассом JLabel.Средство визуализации (один и тот же экземпляр для всех ячеек, настроенных для использования этого средства визуализации) будет просто отображать значок , помеченный , если логическое значение для рендеринга равно true, и значок , не помеченный (илизначок отсутствует), когда логическое значение для рендеринга равно false.

Тогда у вашего обработчика щелчков будет только одна миссия: сделать ячейку, в которой щелкнули, значение true, а не false.Для этого нужно просто изменить соответствующее значение в табличной модели.

Напомним: для хранения данных используется табличная модель.Думайте об этом как о данных, которые вы найдете в базе данных.Будете ли вы держать JLabel в базе данных?Нет, вы бы имели логическое значение, строку или целое число.Таблица может отображать эти данные так, как вам нужно, и в этом заключается задача средства визуализации.

Примечание: остановитесь на венгерской нотации: в Java это не имеет смысла.Это делает код трудным для чтения.Все, кроме примитивных типов, является объектом, и вы не можете назначить значимый префикс каждому возможному типу.Вместо этого используйте удобочитаемые и значимые английские имена: tableModel вместо o_dtb, correctAnswer вместо s_questAns, userAnswer вместо s_userAns.

...