Individual and Not Continuous Jtable's Cell Selection

Individual and not continuous JTable's cell selection

  1. If isn't defined for JTable#setSelectionMode(ListSelectionModel.SINGLE_SELECTION), then CTRL + MOUSE_CLICK

  2. Or do you mean remember last selected?

  3. ListSelectionModel is used by both JTable and JList.

Sample ImageSample ImageSample ImageSample ImageSample Image

import java.awt.Component;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import javax.swing.*;

public class Ctrl_Down_JList {

private static void createAndShowUI() {
String[] items = {"Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat"};
JList myJList = new JList(items) {

private static final long serialVersionUID = 1L;

@Override
protected void processMouseEvent(MouseEvent e) {
int modifiers = e.getModifiers() | InputEvent.CTRL_MASK;
// change the modifiers to believe that control key is down
int modifiersEx = e.getModifiersEx() | InputEvent.CTRL_MASK;
// can I use this anywhere? I don't see how to change the modifiersEx of the MouseEvent
MouseEvent myME = new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), modifiers, e.getX(),
e.getY(), e.getXOnScreen(), e.getYOnScreen(), e.getClickCount(), e.isPopupTrigger(), e.getButton());
super.processMouseEvent(myME);
}
};
JFrame frame = new JFrame("Ctrl_Down_JList");
frame.getContentPane().add(new JScrollPane(myJList));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
createAndShowUI();
}
});
}

JTable select multiple non-contiguous cells with ctrl+click combination

Well this seems to be a common problem with JTables, you can not select non-contiguous cells but you can show "fake" non-contiguous cells.

You can check my solution but is not perfect. In that solution the "shift" selections doesn't work.

The idea is to override isCellSelected(int row, int colum) and changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) of JTable.

So I store the individually selected cells and use them in isCellSelected.

Create these classes fom cell storage :

class Cell {
private int row;

private int column;

public Cell(int row, int column) {
this.row = row;
this.column = column;
}

public boolean is(int r, int c) {
return row == r && column == c;
}
}

class CellSelectionSet {
private ArrayList<Cell> cells = new ArrayList<TestTimeTable.Cell>();

public void add(int r, int c) {
if (!contains(r, c)) {
cells.add(new Cell(r, c));
}
}

public boolean containsOneOrLess() {
return cells.size() <= 1;
}

public boolean contains(int r, int c) {
for (Cell cell : cells) {
if (cell.is(r, c)) {
return true;
}
}
return false;
}

public void clear() {
cells.clear();
}

}

and at JTable you can use that :

this.timeTable = new JTable(this.rowData, this.daysOfTheWeek) {
CellSelectionSet cellSelectionSet = new CellSelectionSet();

@Override
public boolean isCellEditable(int row, int column) {
return false;
}

@Override
public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
super.changeSelection(rowIndex, columnIndex, toggle, extend);

if (toggle) {
cellSelectionSet.add(rowIndex, columnIndex);

} else {
if (extend) {
cellSelectionSet.add(rowIndex, columnIndex);

} else {
// reset
cellSelectionSet.clear();
cellSelectionSet.add(rowIndex, columnIndex);
}
}

}

@Override
public boolean isCellSelected(int row, int column) {
if (cellSelectionSet.containsOneOrLess()) {
// show the default
return super.isCellSelected(row, column);
}
return cellSelectionSet.contains(row, column);
}

};

I hope this helps you.

JTable - Disallow selection and focusing of some cells while allowing others to be selected or focused

Try overriding JTable's changeSelection method with you custom constraints and you'll likely need to disable editing via overriding isCellEditable too. E.g.:

final JTable table = new JTable( data, columnNames ) {
@Override
public void changeSelection( int row, int col, boolean toggle, boolean expand ) {
if( ( row + col )%2 == 0) { // here you set your own rules
super.changeSelection( row, col, toggle, expand );
}
}

@Override
public boolean isCellEditable( int row, int col ) {
return false; // disabling editing separately
}
};

JTable with cell selection and multiple interval selection shows incorrect selection

So I've implemented it in the JTable.

Note that there are several drawbacks to this solution:

  • You cannot use the table.getListSelectionModel to select rows, you need to call table.addRowSelectionInterval
  • trying to select another column next to a selected block will unselect the rows
  • I haven't tested column selection but my guess is that it wouldn't work
  • changing direction when selecting block does not work always

but for the rest it does pretty much what I wanted

/*
* 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);
}
}

The last version is in Joeffice Mercurial repository on bitbucket.org

How to perform multiple cell selection in a jtable with mouse click

For something like this, what I have done myself is create an ArrayList to store the selected cells in. Then refer to that array when you need to know which cells are selected. Then I created a custom cell renderer. In that class, I would check if a cell was in the ArrayList of selected cells, and if it was I would set it to the table cell selected color.

... public class MyTableCellRenderer extends DefaultTableCellRenderer
...

//Defined in your class somewhere
//Add column values to it when clicked on or selected

private final Color selectedColumn = Color.YELLOW;
List<String> selectedCols = new ArrayList<String>();

if (selectedCols.contains(cellValue)) {
tableCell.setBackground(selectedColumn);
} else {
tableCell.setBackground(UIManager.getColor("Table.background"));
}

How to select only cells in one row in a jtable?

Use the setSelectionMode() method from ListSelectionModel interface, and set the selection mode to ListSelectionModel.SINGLE_SELECTION.

This will configure JTable to work with one row at a time selection, blocking selection of multiple rows.

To select single cells, combine the above with setColumnSelectionAllowed(true) on TableColumnModel, and you should get what you need.

JTable or some other Java table class with advanced cell selection?

Doesn't sound like you are really modeling a 'table'. (JTable assumes table semantics and uses a List selection model.) However, I don't think it's that far removed from a matrix, if you are willing to hack the JTable code.

An alternative is your own (yep) component: A JPanel that contains the matrix cells. All keyboard/mouse event processing needs to be delegated to the parent JPanel. I would certainly recommend cloning the relevant subsets and design from JTable (data model, selection model, etc.).

So, basically, you will need 3 classes:

JMatrix, JMatrixModel, JMatrixSelectionModel.

The JMatrix is the extended JPanel with its child components. The JMatrixSelectionModel is the class that will implement the selection rules. The JMatrix should call the selection model on selection events (registered on matrix cells, delegated to handler on the parent JMatrix). The data model is fairly straightforward -- you may even be able to use existing JTableModel.



Related Topics



Leave a reply



Submit