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


Автор: miroque 13.3.2013, 05:36
Здравствуйте.
Пишу собственный ученический проект. Но чтото я запутался во всех этих слушателях и событиях. Помогите разобраться как по умному сделать следующую задачу:
user posted image

На Главном окне, две Панели(выделено фиолетовой рамкой):
Вверху мой компонент MyComponent extends JPanel
Внизу JTable

в MyComponent 3 подпанельки (выделены красным), в каждой из панели ряд из JLabel с текстом (буква или цифра).

Результат работы: Выделяем ячейку, в ту которую хотим заносить символы. И нажимаем мышкой на JLabel с цифрой или буквой, и ее значение заносится в "активную" или "редактируемую" ячейку таблицы.

Вариант некой виртуальной клавиатуры. Только я что то запутался, кто из них должен быть слушателем, а кто события генерит. Или использовать шаблон проектирования "Наблюдатель"? сделать таблицу наблюдателем, а ряды с JLabels сделать субъектами? Но мне кажется можно воспользоваться уже готовыми Listeners, их в каждом из объектов на всякий случай жизни.

Помогите увидеть направление в какую сторону идти?

Автор: dorogoyIV 13.3.2013, 12:17
как то так наверное:
Код

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.util.*;

public class Main extends JFrame
{
    public Main()
    {
        JTable table = new JTable(5, 5);

        JPanel top = new JPanel(new BorderLayout());
        top.add(new MyPanel(27, table), "North");
        top.add(new MyPanel(22, table));
        top.add(new MyPanel(8, table), "South");
        add(top, "North");

        add(new JScrollPane(table));
    }
    
    public static void main(String [] args)
    {
        SwingUtilities.invokeLater(new Runnable() {
        public void run() {
                Main main = new Main();
                main.setDefaultCloseOperation(3);
                main.setBounds(100, 100, 400, 500);
                main.setVisible(true);
            }
        });
    }
}

class MyPanel extends JPanel
{
    MyPanel(int labelsCount, JTable table)
    {
        super(null);
        setBorder(new LineBorder(Color.RED));
        int hgap = 4, vgap = 4;
        int x = 0, y = 0;
        int size = MyLabel.SIZE;

        for(int i = 0; i < labelsCount; i++)
        {
            int r = new Random().nextInt(26) + 65;
            MyLabel ml = new MyLabel((char)r, table);

            if(x > 10)
            {
                x = 0;
                y++;
            }
            ml.setBounds(x * (size + hgap) + hgap, y * (size + vgap) + vgap, size, size);
            add(ml);
            x++;
        }
        setPreferredSize(new Dimension((size + hgap) * 10 + hgap,
                        (y + 1) * (size + vgap) + vgap));
    }
}

class MyLabel extends JLabel
                  implements MouseListener
{
    public static int SIZE = 30;
    char text;
    private JTable table;

    MyLabel(char text, JTable table)
    {
        super(text + "", JLabel.CENTER);
        this.text = text;
        this.table = table;
        setPreferredSize(new Dimension(SIZE, SIZE));
        setBorder(new LineBorder(null));
        addMouseListener(this);
    }

    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}
    public void mousePressed(MouseEvent e){}
    public void mouseReleased(MouseEvent e){}
    public void mouseClicked(MouseEvent e)
    {
        insertSymbol();
    }

    private void insertSymbol()
    {
        int row = table.getSelectedRow();
        int column = table.getSelectedColumn();

        if(row + column >= 0)
        {
            Object value = table.getValueAt(row, column);

            if(value == null)
                value = "";

            table.setValueAt(value.toString() + text, row, column);
        }
    }
}

Автор: miroque 14.3.2013, 07:41
dorogoyIV, спасибо за первую подскзаку!
Сейчас мало времени проверить и соединить решение с моим кодом.
Надеюсь получится проверить на выходных.

Автор: miroque 26.3.2013, 04:31
dorogoyIV, спасибо за подсказку!
Опробовал на выходных этот подход. И увидел, что да, Листенером должны быть эти вот самые "кнопки", которые JLabel. А я то думал что мне нужно реализовывать Листенер на Таблице. Вроде как, Таблица слушает, а нажал ли кто нибудь на "кнопку" и сама у себя смотрит а какая ячейка активная, и в нее записывать информацию с JLabel. Опробовал на практике, и получилось, что Листенером должны быть JLabel, в частности MouseListener.
А дальше основная подсказка еще вот в этом получилась
Код

    public void mouseClicked(MouseEvent e)
    {
        insertSymbol();
    }
    private void insertSymbol()
    {
        int row = table.getSelectedRow();
        int column = table.getSelectedColumn();
        if(row + column >= 0)
        {
            Object value = table.getValueAt(row, column);
            if(value == null)
                value = "";
            table.setValueAt(value.toString() + text, row, column);
        }
    }


Но поскольку у меня в таблице не просто текст лежит, а объект, который можно представить одной строчкой, с тремя полями. То я уже использую свой класс который расширяет TableModel. И тут для меня открылось, что мне еще нужно изучать подход, Вид-Логика-Представление. Т.е. свои объекты я запихал в TableModel, и эту модель в JTable положил, и теперь взаимодействие изменилось для меня.
Что то нужно вытворять на JTable и как на эти действия будет регировать TableModel. Интересная тема, буду дальше исследовать и изучать.
Спасибо за направление моей мысли. Ответ я получил, тему закрываю решенной.

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