0

セルを自由に選択できるテーブルが欲しいです。

このために、 ListSelectionModel.MULTIPLE_INTERVAL_SELECTION とtable.setCellSelectionEnabled(true)を使用しました。

私には2つの問題があります:

  • メソッドtable.addRowSelectionIntervalはセルを選択しません
  • 2 つのブロックを選択すると、同じ行と列が選択されているセルも選択されます。たとえば、B2-D4 を選択してから F7 を選択します。これにより、B7-D7 と F2-F4 も選択されます。

これらの問題を再現するプログラムは次のとおりです。

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

public class JTableCellSelection {
    public static void showDemo(JComponent demo, String title) {
        JFrame mainFrame = new JFrame();
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.setTitle(title);
        JPanel contentPanel = new JPanel(new BorderLayout());

        contentPanel.add(demo);

        mainFrame.add(contentPanel);
        mainFrame.pack();
        mainFrame.setVisible(true);
    }

    public static void main(String[] args) {
        JTable table = new JTable(10, 10);
        table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        table.setCellSelectionEnabled(true);
        table.addRowSelectionInterval(6, 7); // Select 2 lines
        showDemo(new JScrollPane(table), "Select a block and some rows");
    }
}

テーブル セル レンダラーの isSelected に頼るのではなく、自分で選択を確認する必要があるように感じます。

4

2 に答える 2

1

だから私はそれをJTableに実装しました。

このソリューションにはいくつかの欠点があることに注意してください。

  • table.getListSelectionModelを使用して行を選択することはできません。table.addRowSelectionIntervalを呼び出す必要があります
  • 選択したブロックの横にある別の列を選択しようとすると、行の選択が解除されます
  • 私は列の選択をテストしていませんが、それは機能しないと思います
  • ブロックを選択するときに方向を変えることが常に機能するとは限りません

しかし、残りの部分については、私が望んでいたことをほぼ実行します

/*
 * Copyright 2013 Japplis.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.awt.Point;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import javax.swing.JTable;
import javax.swing.table.TableModel;

/**
 * The JTable used to display data.
 * This class is only to fix bugs or improve existing functionalities.
 *
 * @author Anthony Goubard - Japplis
 */
public class SheetTable extends JTable {

    private Map<Integer, Set<Integer>> selectedCells = new HashMap<>();
    private Point firstExtendCell;

    public SheetTable(TableModel tableModel) {
        super(tableModel);
    }

    @Override
    public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
        if (toggle && isCellSelected(rowIndex, columnIndex) && !extend) {
            selectedCells.get(rowIndex).remove(columnIndex);
        } else {
            if (!toggle && !extend) {
                selectedCells.clear();
            }
            Set<Integer> selectedColumns = selectedCells.get(rowIndex);
            if (selectedColumns == null) {
                selectedColumns = new TreeSet<>();
                selectedCells.put(rowIndex, selectedColumns);
            }
            selectedColumns.add(columnIndex);
            if (!extend) {
                firstExtendCell = new Point(rowIndex, columnIndex);
            } else {
                for (int i = Math.min(firstExtendCell.x, rowIndex); i <= Math.max(firstExtendCell.x, rowIndex); i++) {
                    for (int j = Math.min(firstExtendCell.y, columnIndex); j <= Math.max(firstExtendCell.y, columnIndex); j++) {
                        selectedCells.get(i).add(j);
                    }
                }
            }
        }
        super.changeSelection(rowIndex, columnIndex, toggle, extend);
    }

    @Override
    public void addRowSelectionInterval(int index0, int index1) {
        for (int i = index0; i < index1; i++) {
            selectedCells.remove(i);
        }
        super.addRowSelectionInterval(index0, index1);
    }

    @Override
    public void removeRowSelectionInterval(int index0, int index1) {
        for (int i = index0; i < index1; i++) {
            selectedCells.remove(i);
        }
        super.removeRowSelectionInterval(index0, index1);
    }

    @Override
    public void selectAll() {
        selectedCells.clear();
        super.selectAll();
    }

    @Override
    public void clearSelection() {
        if (selectedCells != null) {
            selectedCells.clear();
        }
        super.clearSelection();
    }

    @Override
    public boolean isCellSelected(int row, int column) {
        if (!getSelectionModel().isSelectedIndex(row)) {
            return false;
        }
        if (getSelectionModel().isSelectedIndex(row) && selectedCells.get(row) == null) {
            return true;
        }
        return selectedCells.get(row).contains(column);
    }
}

最後のバージョンは、bitbucket.orgのJoefficeMercurialリポジトリにあります

于 2013-03-23T18:54:41.160 に答える
0

私はいくつかの実験を行い、ここのドキュメントも読みました。それはsetCellSelectionEnabled()方法を言います:

このテーブルで列選択と行選択の両方を同時に存在できるかどうかを設定します。設定すると、テーブルは行と列の選択モデルの共通部分を選択されたセルとして扱います。

showDemo()行間隔を追加した後、選択した行と列が何であるかを確認する直前に、デバッグ目的で2行のコードを追加しました。

public static void main(String[] args) {
    JTable table = new JTable(10, 10);
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setCellSelectionEnabled(true);
    table.addRowSelectionInterval(6, 7); // Select 2 lines

    // Let's see what rows and columns have been selected 

    System.out.println("Rows: " + Arrays.toString(table.getSelectedRows()));
    System.out.print("Columns: " + Arrays.toString(table.getSelectedColumns()));

    showDemo(new JScrollPane(table), "Select a block and some rows");
}

そして私はこの出力を得ました:

Rows: [6, 7]
Columns: []

これは、なぜaddRowSelectionInterval期待どおりに機能しないのかを説明しています。不足している部分を追加するのは簡単です。

    ...
    table.addRowSelectionInterval(6, 7); // Select 2 lines
    table.addColumnSelectionInterval(0, 9); // and Select ** ALL** the columns
    ...

他の観察についても同様の正当化を行うことができます。

于 2013-03-22T12:15:03.843 に答える