Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > Как повернуть JTable на 90 градусов в лево


Автор: diablero 3.12.2006, 00:16
Для того чтобы результат запроса к базе данных был более информативным и читаемым, мне необходимо повернуть таблицу.
Таблица включает в себя строки, чекбоксы,  картинки, даты ...


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


Автор: w1nd 3.12.2006, 02:00
А почему не получилось?

Автор: diablero 5.12.2006, 19:02
Изначально на соответсвующие столбцы у меня были назначенны собственные CellRenderer'ы, а при перевороте я не знаю чтто делать. Назначать их на соответсвующие ячейки таблицы? Только я не знаю как...

Автор: powerOn 5.12.2006, 19:13
Цитата(diablero @  5.12.2006,  19:02 Найти цитируемый пост)
Изначально на соответсвующие столбцы у меня были назначенны собственные CellRenderer'ы, а при перевороте я не знаю чтто делать. Назначать их на соответсвующие ячейки таблицы? Только я не знаю как... 


а может таблицу не поворачивать, а повенрнуть рендерер?

Автор: diablero 5.12.2006, 19:31
>а может таблицу не поворачивать, а повенрнуть рендерер?

Поясните? 

Автор: powerOn 5.12.2006, 20:01
Вот есть http://jroller.com/page/henribenoit?entry=vertical_labels вывода вертикального текста в JLabel. Можно попробовать его в качестве рендерера для ячейки таблицы. Теоретически, должно получиться. Тогда и таблицу поворачивать не придется...  smile 

Автор: diablero 5.12.2006, 20:24
Нееет, суть не в этом.
Мне не ячейки надо повернуть, а всю таблицу, т.е. чтобы прокручивать столбцы надо было не в право, а в низ

Исходная:

   1     |    2     |   3     |   
текст |  текст |текст |
    

Что нужно получить:
_________|
1   |  текст |
_________|
2   |  текст |
_________|
3   |  текст |



Автор: powerOn 5.12.2006, 20:39
Т.е. у Вас просто направление вывода данных меняется ...  как бы транспонируются... Тогда лучше модель таблицы соответствующим образом переписать... Что бы первая строка была первым столбцом, вторая вторым и тд... 

Автор: diablero 5.12.2006, 21:32
Тогда как соответствующий рендерер назначить соответсвующей строке, или ячейки?

Автор: LSD 5.12.2006, 21:38
Назначай рендерер на класс:
Код
table.setDefaultRenderer(String.class, stringRenderer);

Автор: diablero 5.12.2006, 23:48
Код
table.setDefaultRenderer(Object.class, stringRenderer);
table.setDefaultEditor(Object.class, new DataTableCellEditor());



Для транформации имею две модели таблицы. 
Исходная:
Код

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;

    public class DatabaseTableModel extends AbstractTableModel
    {
        private ArrayList columnNames = new ArrayList();
        private ArrayList columnTypes = new ArrayList();
        private ArrayList data = new ArrayList();
        private boolean editable;

        public DatabaseTableModel(boolean editable)
        {
            this.editable = editable;
        }
        public int getRowCount()
        {
            synchronized(data)
            {
               return data.size();
            }
        }
        public int getColumnCount()
        {
            return columnNames.size();
        }
        public Class getColumnClass(int column)
        {
            return (Class)columnTypes.get(column);
        }
        public String getColumnName(int column)
        {
            return (String)columnNames.get(column);
        }
        public Object getValueAt(int row, int column)
        {
            synchronized(data)
            {
                return ((ArrayList)data.get(row)).get(column);
            }
        }

        public boolean isEditable(int row, int column)
        {
            return editable;
        }

        public void setValueAt(Object value, int row, int column)
        {
            synchronized(data)
            {
                ((ArrayList)data.get(row)).set(column, value);
            }
        }

        private Class getClassName(String type, String _class)
        {
            Class ClassName = null;
            if (type=="BLOB")
                return Icon.class;
            else
            {
                try
                    {ClassName=Class.forName(_class);}
                catch(Exception err)
                    {}
            return ClassName;
            }
        }


        public void setDataSource(ResultSet rs) throws Exception
        {
            data.clear();
            columnNames.clear();
            columnTypes.clear();

            ResultSetMetaData rsmd = rs.getMetaData();
            int columnCount = rsmd.getColumnCount();
            
            for(int i=0; i<columnCount; i++)
            {
                columnNames.add(rsmd.getColumnName(i+1));
                Class type=getClassName(rsmd.getColumnTypeName(i+1),rsmd.getColumnClassName(i+1));
                columnTypes.add(type);
            }
           fireTableDataChanged();

            while(rs.next())
            {
                ArrayList row = new ArrayList();
                for(int i=0; i<columnCount; i++)
                {
                  if(columnTypes.get(i) == Icon.class)
                  {
                      byte image []= rs.getBytes(i+1);
                      if (image!=null)
                        row.add(new ImageIcon(image));
                      else
                        row.add(null);
                  }
                  else
                       row.add(rs.getObject(i+1));
                }

                synchronized(data)
                {
                    data.add(row);

                    this.fireTableRowsInserted(data.size()-1, data.size()-1);
                }

            }
        }
    }


И транспонированная:
Код

import javax.swing.table.AbstractTableModel;
import java.sql.ResultSet;

public class TransposeTableModel extends AbstractTableModel
{
    DatabaseTableModel model;
    public TransposeTableModel(boolean editable)
    {
        model = new DatabaseTableModel(editable);
    }
    public boolean isEditable(int row, int column)
    {
        return model.isEditable(column, row);
    }
    public int getRowCount()
    {
        return model.getColumnCount();
    }

    public int getColumnCount()
    {
        return model.getRowCount();
    }

    public Object getValueAt(int row, int column)
    {
        return model.getValueAt(column, row);
    }
    public void setDataSource(ResultSet rs) throws Exception
    {
        model.setDataSource(rs);
    }
}

Для отображения использую следующий рендерер:
Код

public class DataTableCellRenderer extends DefaultTableCellRenderer
{
    public Component getTableCellRendererComponent(JTable table, Object value,
                    boolean isSelected, boolean hasFocus, int row, int column)
    {
        TableColumnModel columnModel = table.getColumnModel();

        if(value==null) value = new String();
        if(value instanceof String)
        {
            JTextArea text = new JTextArea();
            text.setWrapStyleWord(true);
            text.setLineWrap(true);

            if (isSelected)
            {
                text.setOpaque(true);
                text.setForeground(table.getSelectionForeground());
                text.setBackground(table.getSelectionBackground());
            }
            else
            {
                text.setForeground(table.getForeground());
                text.setBackground(table.getBackground());
            }
            text.setFont(table.getFont());
            text.setText((String) value);
            text.setSize(columnModel.getColumn(column).getWidth(), 100000);

            int height = (int)text.getPreferredSize().getHeight();

            if (table.getRowHeight(row) != height)
                table.setRowHeight(row, height);

            return text;
        }
        if(value instanceof ImageIcon)
        {
            setIcon((ImageIcon)value);
            setHorizontalAlignment(JLabel.CENTER);
            setSize(columnModel.getColumn(column).getWidth(), 100000);
            int height = (int)getPreferredSize().getHeight();
            if (table.getRowHeight(row) != height)
                table.setRowHeight(row, height);

            return this;
        }
        return null;
    }
}

Редактор
Код

public class DataTableCellEditor extends AbstractCellEditor implements TableCellEditor
{
    private JTextArea text;

    public DataTableCellEditor()
    {
        text = new JTextArea();
        text.setWrapStyleWord(true);
        text.setLineWrap(true);
    }
    public Object getCellEditorValue()
    {
        return text.getText();
    }

    public Component getTableCellEditorComponent(JTable table, Object value,
                                                 boolean isSelected,
                                                 int row, int column) {
        text.setText((String)value);
        return null;
    }
    
}


Автор: w1nd 6.12.2006, 00:27
В вашей исходной модели переопределен метод getColumnClass(), а в транспонированной - нет. Реализация этого метода в AbstractTableModel возвращает Object.class.

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

Автор: diablero 6.12.2006, 14:25
Чего -то с реализацией метода getColumnClass() проблема, в транспонированной таблице, не знаю как ему строки подпихивать...

>А еще замечу, что менять свойства таблицы из рендерера не стоит, т. к. каждое такое изменение вызывает очередную перерисовку.
А я то думал, что она перерисовываеться

Автор: LSD 7.12.2006, 13:06
Цитата(diablero @  6.12.2006,  14:25 Найти цитируемый пост)
Чего -то с реализацией метода getColumnClass() проблема, в транспонированной таблице, не знаю как ему строки подпихивать...

Тут уже все равно, что ему выдавать. Все равно класс задается для колонки в целом, а не для отдельных ее элементов. Так что пусть возвращает Object.class.

Надо написать такой рендерер, который бы определял реальный тип объекта (instanceof), и в зависимости от этого отображал его.

Автор: diablero 7.12.2006, 16:23
to w1nd
>А еще замечу, что менять свойства таблицы из рендерера не стоит, т. к. каждое такое изменение вызывает очередную перерисовку.

А где тогда выставлять размер ячеек?  Данные то все разные (размер картинок, длина текста)

Автор: diablero 8.12.2006, 23:37
Как обрабатывать события редактора. Что пользователь закончил редактировать? Что переключился на другую ячейку?

Автор: LSD 9.12.2006, 02:21
Модератор: Пожалуйста, один топик - один вопрос.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)