I want to create table of elements with checkboxes in which one could change the state of checkbox by: 1) Clicking on checkbox, 2) Clicking on row. Unfailingly and fastly.
I've tried:
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.*;
public class Example {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setSize(280, 300);
shell.setText("FooTable");
Table table = new Table(shell, SWT.CHECK | SWT.BORDER | SWT.V_SCROLL| SWT.H_SCROLL);
String[] titles = { "Column" };
for (int loopIndex = 0; loopIndex < titles.length; loopIndex++) {
TableColumn column = new TableColumn(table, SWT.NULL);
column.setText(titles[loopIndex]);
}
for (int loopIndex = 0; loopIndex < 5; loopIndex++) {
TableItem item = new TableItem(table, SWT.NULL);
item.setText("Item " + loopIndex);
}
for (int loopIndex = 0; loopIndex < titles.length; loopIndex++) {
table.getColumn(loopIndex).pack();
}
table.setBounds(25, 25, 220, 200);
table.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if (event.detail == SWT.CHECK) {
System.out.println("You checked " + event.item);
}
else {
System.out.println("You selected " + event.item);
TableItem ti = (TableItem)event.item;
ti.setChecked(!ti.getChecked());
}
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
But with this I've got at least 2 problems:
1) When a row is selected and I click on checbox, the two listeners will at the same time change the state of checkbox, so in the end there is no effect (bad).
2) When I double-click on a row, there again won't be any effect (bad), but when I double-click on checkbox (while row is not selected) I can clearly see checkbox changing it's state twice (good).
So how can I fix this or achieve it in another way?
Edit
I solved my problem by using multiple buttons instead of table, in this way
Button b = new Button(this, SWT.CHECK | SWT.WRAP);
b.setText("item");
But through it all, question remains open.
In order to solve your first problem, you can check if the checked item is also selected and revert the check in this case.
The resulting selection listener would look like this:
table.addListener( SWT.Selection, new Listener() {
public void handleEvent( Event event ) {
if( event.detail == SWT.CHECK ) {
System.out.println( "You checked " + event.item );
if( table.indexOf( ( TableItem )event.item ) == table.getSelectionIndex() ) {
TableItem ti = ( TableItem )event.item;
ti.setChecked( !ti.getChecked() );
}
} else {
System.out.println( "You selected " + event.item );
TableItem ti = ( TableItem )event.item;
ti.setChecked( !ti.getChecked() );
}
}
} );
To solve the double click issue, you can add a default selection listener that changes the check mark if the item (and not the check box) is double clicked
table.addListener( SWT.DefaultSelection, new Listener() {
#Override
public void handleEvent( Event event ) {
if( event.detail == SWT.NONE ) {
TableItem ti = ( TableItem )event.item;
ti.setChecked( !ti.getChecked() );
}
}
} );
Apart from the technical issues, I find the handling at least unusual and plain annoying when using the keyboard. Make sure that this behavior is what your users actually expect.
It works when clicking check box. It returns all selected row.
#Inject private AddSelectedItem addSelectedItem; //you can also create instance with new addSelectedItem()
...
table = new Table(shell, SWT.CHECK | SWT.BORDER);
table.addSelectionListener(addSelectedItem);
...
Class is created and implements SelectionListener.
public class AddSelectedItem implements SelectionListener
{
#Override
public void widgetSelected(SelectionEvent event)
{
((/*TypeCast - Your Return Type - YourTypeClass*/) event.item.getData()).switchSelected();
}
}
...
public class Test // YourTypeClass
{
private int a,b; // These are column variables at the table
private boolean flag;
public Test(){ //Constructor
...
this.flag=false;
}
public void switchSelected()
{
if (flag == false)
flag = true;
else
flag = false;
}
}
Also, implement arraylist and add your items into the list according to flag value. If it was selected (flag==true), add to the arraylist. Then you can reach every item in your arraylist.
List<Test > list = new ArrayList<Test >();
To sum up, you should define class with selection flag, then add list according to flag value. Then you can print list (selected items and their values) or write list to the file.
Example:
Selection a b
--------- --- ---
checkBox 1 2
checkBox 2 3
.......... .. ..
If checkBox is checked, flag returns true. Add it to the list.
SWT Table checking box by selecting row or checking the box
Table Column can add images like checked or unchecked
click column checked to all row can checked
and
click column unchecked to all row can unchecked
TableColumn tblclmnNewColumn_1 = new TableColumn(table, SWT.LEFT);
tblclmnNewColumn_1.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
System.out.println("Total Row Count:"+table.getItemCount());
TableItem item[] = table.getItems();
//get all the table items
for(int i=0;i<table.getItemCount();i++)
{
//Table_Column Checked or Not
if(item[i].getChecked())
{
//table items unchecked
item[i].setChecked(false);
tblclmnNewColumn_1.setImage(SWTResourceManager.getImage("D:\\Icon\\uncheck.png"));
}
else
{
//table items checked
item[i].setChecked(true);
tblclmnNewColumn_1.setImage(SWTResourceManager.getImage("D:\\Icon\\check.png"));
}
}
}
});
tblclmnNewColumn_1.setMoveable(true);
tblclmnNewColumn_1.setToolTipText("All Check");
tblclmnNewColumn_1.setImage(SWTResourceManager.getImage("D:\\Icon\\uncheck.png"));
tblclmnNewColumn_1.setWidth(36);
Fully describe visit this code :: de)select all” check box in an SWT Table header :
How can I put a "(de)select all" check box in an SWT Table header?
Related
I'm trying to make a Sudoku Game in JavaFX. I made the 9x9 grid using GridPane and TextField.
Now I want to change the background color of the TextField when user clicks inside it. To check that everyting is fine I am prining the target od the MouseEvent.
My problem is that when I click in the center of TextField, the target is Pane and when i I click elsewhere the target is my GridPane and the background color is changing.
What should I do? I can't figure out how to do it!
public class SudokuGrid {
public static final int GRID_SIZE = 9;
private TextField[][] sudokuCells;
private GridPane sudokuGrid;
public SudokuGrid () {
sudokuCells = new TextField[GRID_SIZE][GRID_SIZE];
createSudokuGrid();
for (int row = 0; row < GRID_SIZE; row++) {
for(int col = 0; col < GRID_SIZE; col++) {
sudokuCells[row][col] = new TextField() {
#Override
public void replaceText(int start, int end, String text) {
// If the replaced text would end up being invalid, then simply
// ignore this call!
if (text.matches("[1-9]|\\s")) {
super.setText(text);
}
}
};
sudokuCells[row][col].setPrefSize(60, 60);
sudokuCells[row][col].setStyle("-fx-background-color: yellow;");
sudokuGrid.add(sudokuCells[row][col], col, row);
sudokuGrid.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
Object source = e.getTarget();
System.out.println(source);
if(source instanceof TextField) {
((TextField) source).setStyle("-fx-background-color: green;");
}
}
});
}
}
sudokuGrid.setPrefSize(270, 270); // 30 * 9
sudokuGrid.setGridLinesVisible(true);
}
private void createSudokuGrid() {
sudokuGrid = new GridPane();
for (int i = 0; i < GRID_SIZE; i++) {
RowConstraints rc = new RowConstraints();
rc.setVgrow(Priority.ALWAYS) ; // allow row to grow
rc.setFillHeight(true); // ask nodes to fill height for row
// other settings as needed...
sudokuGrid.getRowConstraints().add(rc);
ColumnConstraints cc = new ColumnConstraints();
cc.setHgrow(Priority.ALWAYS) ; // allow column to grow
cc.setFillWidth(true); // ask nodes to fill space for column
// other settings as needed...
sudokuGrid.getColumnConstraints().add(cc);
}
}
The source of the event is the object on which you set the event filter; i.e. in this case it is sudokuGrid. So the condition
if (source instanceof TextField)
in your handler will never be true, since the only possible source is the sudokuGrid.
If you want to change the background color of the text field, you can add the event filter to the text field itself:
TextField sudokuCell = sudokuCells[row][col];
sudokuCell.addEventFilter(MouseEvent.MOUSE_PRESSED, e ->
sudokuCell.setStyle("-fx-background-color: green;"));
Better still would be to respond to changes in the text field's focused property (because using a mouse listener will not change the background if the user uses the Tab key to navigate to different text fields):
TextField sudokuCell = sudokuCells[row][col];
sudokuCell.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
if (isNowFocused) {
sudokuCell.setStyle("-fx-background-color: green;");
} else {
sudokuCell.setStyle("");
}
});
And even better would just be to use an external css file to do this:
sudoku-grid.css:
.text-field:focused {
-fx-background-color: green ;
}
and then in your Java code associate the CSS file with the grid:
sudokuGrid.getStyleSheets().add("sudoku-grid.css");
and remove the handlers entirely.
I create several JLists by using DefaultListmModel, so I can add, edit and delete items in those JLists.
How can I hide the selection the user made?
So like the user clicks in JList 1 to edit the value with index 2 by double clicking on the item. So now the item with index value 2 is selected in the UI and it's blue.
My Question is: How can I hide this, so after editing/adding items in the JList, what do I have to do that the item which was selected isn't blue, so that you can't see what you selected before.
clearSelection() isn't working.
My code is the following (I shortened the JOptionPane stuff and the if else part):
for (int i=0; i < StringArray.length; i++) {
DefaultListModel<String> model = new DefaultListModel<String>();
for (int j=0; j < StringArray[i].length; j++) {
model.addElement(StringArray[i][j]);
if((StringArray[i].length -1)== j) {
listbox = new JList<String>(model);
Panel.add(listbox);
listbox.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int index = listbox.locationToIndex(e.getPoint());
Object[] options = {"Add", "Edit", "Delete"};
//.... JOptionPane
if (ADDING) {
String tmpAddValue = JOptionPane...
model.addElement(tmpAddValue);
}
else if (EDITING) {
String tmpValue = JOptionPane...
model.setElementAt(tmpValue, index);
}
else if (DELETING) {
model.removeElementAt(index);
}
else {
System.out.println("No Button pushed");
}
listbox.clearSelection();
}
}
});
}
}
Thanks
In SWT I want to show a Table with 4 columns: 1st a number, 2nd a String, 3rd a checkBox and 4th a radio button.
Once all rows are set, I want to add another row for 3rd column (check all/none), and 4th column (clean radio selected).
This is the code (It compiles, but I haven't tested, yet):
//Create table
Table table = new Table(layoutComposite, SWT.BORDER);
table.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL));
String[] tableItems = new String[] {"", "Player", "Show", "Highlight"};
int[] tableSizes = new int[] {30, 150, 20, 20};
// Header Columns and sizes for table
for (int i = 0; i < tableItems.length; i++) {
TableColumn tableColumn = new TableColumn(table, SWT.NONE);
tableColumn.setText(tableItems[i]);
tableColumn.setWidth(tableSizes[i]);
}
table.setHeaderVisible(true);
table.setLinesVisible(false);
// Create items (void)
for (int i = 0; i < positions.size(); i++) {
new TableItem(table, SWT.NONE);
}
TableItem[] items = table.getItems();
// Check and Radio Buttons
Button[] checks = new Button[items.length + 1];
Button[] radios = new Button[items.length + 1];
// Add elements
for (int i = 0; i < items.length + 1; i++) {
// Pos and Player only in first items.length rows
if (i < items.length) {
items[i].setText(0, String.valueOf(positions.get(i).getPos()));
items[i].setText(1, positions.get(i).getPlayer().getPlayerName());
}
TableEditor editorCheck = new TableEditor(table);
checks[i] = new Button(table, SWT.CHECK);
checks[i].pack();
checks[i].setSelection(true);
editorCheck.minimumWidth = checks[i].getSize().x;
editorCheck.setEditor(checks[i], items[i], 2);
TableEditor radioCheck = new TableEditor(table);
radios[i] = new Button(table, SWT.RADIO);
radios[i].pack();
radios[i].setSelection(false);
radioCheck.minimumWidth = radios[i].getSize().x;
radioCheck.setEditor(radios[i], items[i], 3);
}
table.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
if (e.detail == SWT.CHECK) {
if (e.item instanceof Button) {
// TODO:
// Get checked item selected
// If last row (ie: == checks[items.length]), select or unselect all check related buttons
//
//((Button)e.item).get // Problem here!!!!
}
}
else if (e.detail == SWT.RADIO) {
// TODO:
// Get radio selected
// If last row (ie: radios[items.length]), clean selected item (if any)
}
// TODO Auto-generated method stub
super.widgetSelected(e);
}
});
Now I need to add a Listener over check and radio buttons. My question is: How do I know which check or radio button is selected?
should I do something like this?
for (int i = 0; i < checks.length; i++) {
if (e.item == checks[i]) { // found selected
if (i == checks.length -1 ) { // last one
// Select or unselect all
}
// doStuff () ;
}
}
If this is correct, Is there an easy way to know which is selected? If not, how can I do it?
Any other hint will be very welcome.
you can add a selection listener to each checkbox and radio button after you create them:
checks[i].addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent event) {
// your code here...
// get the current checkbox/radio button from the event:
Widget src = event.widget;
// ...
}
});
do the same with radio buttons:
radios[i].addSelectionListener(...);
i hope this helps you. enjoy.
i want to add a cloumn to a jtable when a radio button is being clicked. but when i click it twice two columns are being added to the table. here's my code
dtm = (DefaultTableModel) viewTable.getModel();
dtm.setRowCount(0);
TableColumnModel model=viewTable.getColumnModel();
boolean found=false;
for (int i = 0; i < viewTable.getColumnCount(); i++) {
if (model.getColumn(i).getIdentifier().equals("customer Id")) {
found=true;
break;
}
if (found==false) {
dtm.addColumn("customer Id");
}
don't know how to fix it..
This code would help you. Call the below method on actionPerformed of the check box and if it is true. Validating it based on the column header.
private static void addColumn( final JTable table, final String newColumnHeader )
{
final JTableHeader header = table.getTableHeader();
final int columnCount = header.getColumnModel().getColumnCount();
boolean addColumn = true;
for( int index = 0; index < columnCount; index ++ )
{
final Object headerValue = header.getColumnModel().getColumn(index).getHeaderValue();
if( newColumnHeader.equals( headerValue ) )
{
JOptionPane.showMessageDialog(null, "Column already exists" );
addColumn = false;
break;
}
}
if( addColumn )
{
final TableColumn newCol = new TableColumn();
newCol.setHeaderValue(newColumnHeader);
table.getColumnModel().addColumn(newCol);
}
}
It is good to disable the checkbox if it is already clicked ;) if you do not want a huge code.
This is a clumsy solution but it will work.
You can create a new boolean variable in your class and this variable represents if a column was set or not.
Like:
class MyClass{
boolean isColumnAdded
public MyClass(){
isColumnAdded = false;
}
private void radioButtonActionPerformed(java.awt.event.ActionEvent evt){
if(!isColumnAdded){
//add column
isColumnAdded = true;
}
}
}
To start with, JRadioButton has a selected property. You should be checking this state to determine if the column needs to be removed or added...
Assume that each column name is unique, you could use something like...
TableColumnModel model = viewTable.getColumnModel();
int index = -1;
try {
index = model.getColumnIndex("customer Id");
} catch (IllegalArgumentException e) {
// I know, sucks...
}
if (index < 0) {
// Add new column, if JRadioButton.isSelected
} else {
// Remove old column...
// JRadioButton.isSelected is false...
}
To find and add/remove the column.
Have a look at How to Use Buttons, Check Boxes, and Radio Buttons for some more details
How can I disable JTable's default behaviour of returning to the first row, when tab key is pressed in the last cell of the table? Instead the current cell should keep its focus.
The short answer: find the action that's bound to the Tab, wrap it into a custom action that delegates to the original only if not in the last cell and replace the original action with your custom implemenation.
In code:
KeyStroke keyStroke = KeyStroke.getKeyStroke("TAB");
Object actionKey = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
.get(keyStroke );
final Action action = table.getActionMap().get(actionKey);
Action wrapper = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
JTable table = (JTable) e.getSource();
int lastRow = table.getRowCount() - 1;
int lastColumn = table.getColumnCount() -1;
if (table.getSelectionModel().getLeadSelectionIndex() == lastRow
&& table.getColumnModel().getSelectionModel()
.getLeadSelectionIndex() == lastColumn) {
return;
}
action.actionPerformed(e);
}
};
table.getActionMap().put(actionKey, wrapper);