Add selectListener to table in SWT - java

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.

Related

How can I dynamically change the number of items in a JComboBox

private void dropDownMenu(JPanel jp1, String prodId){
int len = storeManager.getInv().getStockAmount(prodId);
int[] nums = new int[len];
String[] numPossible = new String[len];
for (int i=0; i<len; i++){
nums[i] = i+1;
}
for (int i=0; i<len; i++){
numPossible[i] = String.valueOf(nums[i]);
}
JComboBox<String> cb = new JComboBox<String>(numPossible);
JButton okButton = new JButton("Add To Cart");
okButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Product p1 = storeManager.getInv().getProd(prodId);
String quan = (String) cb.getSelectedItem();
int quantity = Integer.parseInt(quan);
if (quantity > storeManager.getInv().getStockAmount(prodId)) {
System.out.println("Not Enough Stock.");
} else {
storeManager.getCart().addToCart(p1, quantity);
storeManager.getInv().removeStockAmount(prodId, quantity);
//update the dropdown menu here
}
}
});
jp1.add(cb);
jp1.add(okButton);
}
Essentially what i am looking for is that whenever i select a number from the drop down menu, i want the number of items in the menu to be reduced by the amount that was added to cart. for example if i add 5 to cart then i want the dropdown menu to go from allowing me to choose 10 to 5 only.
Image of GUI
As a thought...Instead of doing all these conversions from integer to string and string to back to integer in order to fill your combo box, why not just have a combo box of Integer? You're dealing initially with integer quantity values anyways:
JComboBox<Integer> cb = new JComboBox<>();
int len = storeManager.getInv().getStockAmount(prodId);
for (int i = 1; i <= len; i++) {
cb.addItem(i);
}
cb.setSelectedIndex(0);
Your action listener might look something like this now:
okButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Product p1 = storeManager.getInv().getProd(prodId);
int quantity = (int) cb.getSelectedItem();
/* This 'if' statement below would be moot if the Combo-Box
is properly updated unless editing is allowed in the combo
which in this case...disable that feature. */
if (quantity > storeManager.getInv().getStockAmount(prodId)) {
System.out.println("Not Enough Stock.");
} else {
storeManager.getCart().addToCart(p1, quantity);
len = storeManager.getInv().removeStockAmount(prodId, quantity);
cb.removeAllItems();
for (int i = 1; i <= len; i++) { cb.addItem(i); }
cb.setSelectedIndex(0);
}
}
});
Possibly better yet would be to utilize the JSpinner component instead of a Combo Box. A drop-down list in this use case always seems a bit obtrusive in my opinion.

JavaFX - Clicking inside GridPane prints out Pane instead of TextField

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.

SWT TableItem getText doesn't return what I expect

I want to swap two texts in TableItems. Firstly, I set the text, then I check which TableItems are selected, save them in 2 variables and overwrite them. But I get these strings instead of the message I wanted:
[Lorg.eclipse.swt.widgets.TableItem;#6fadae5d
The part after the # is always different, I guess it's an ID or something but I can't find a solution. Here's the code snippets. groupsList is a String array.
for (int i = 1; i <= logic.amountOfGroups; i++) {
Table table = new Table(shell, SWT.MULTI | SWT.BORDER);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
for (int j = 0; j < logic.personsInGroup; j++) {
TableItem tableItem_1 = new TableItem(table, SWT.NONE);
tableItem_1.setText(logic.groupsList.get(i - 1)[j]);
}
tableList.add(table);
}
So I wrote the content into the TableItems, then I want to swap them:
swapButton = new Button(shell, SWT.NONE);
swapButton.setText("Swap");
swapButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseDown(MouseEvent e) {
int[] playerIndices = new int[2];
int[] groupIndices = new int[2];
int i = 0;
String toBeSwappedZero = "";
String toBeSwappedOne = "";
for (Table table : tableList) {
if (table.getSelectionCount() == 1) {
if (toBeSwappedZero == "") {
groupIndices[0] = i;
playerIndices[0] = table.getSelectionIndex();
toBeSwappedZero = table.getSelection().toString();
} else {
groupIndices[1] = i;
playerIndices[1] = table.getSelectionIndex();
toBeSwappedOne = table.getSelection().toString();
}
}
if (table.getSelectionCount() == 2) {
playerIndices = table.getSelectionIndices();
groupIndices[0] = i;
groupIndices[1] = i;
toBeSwappedZero = table.getItem(playerIndices[0]).getText();
toBeSwappedOne = table.getItem(playerIndices[1]).getText();
}
i++;
}
System.out.println(toBeSwappedOne);
tableList.get(groupIndices[0]).getItem(playerIndices[0]).setText(toBeSwappedOne);
tableList.get(groupIndices[1]).getItem(playerIndices[1]).setText(toBeSwappedZero);
}
});
Here's the GUI
Take a look these lines in your MouseAdapter:
if (table.getSelectionCount() == 1) {
if (toBeSwappedZero == "") {
// ...
toBeSwappedZero = table.getSelection().toString();
} else {
// ...
toBeSwappedOne = table.getSelection().toString();
}
}
Notice that Table.getSelection() returns an array of TableItem objects. As #greg-449 pointed out, you'll get [Lorg.eclipse.swt.widgets.TableItem;#XXXXXXXX if you call toString() on that array.
In each of those two cases you've already checked that there is only one TableItem selected, so you can safely do table.getSelection()[0] to access that TableItem (Alternatively, you could do table.getItem(table.getSelectionIndex()) after verifying that there is at least one and only one item selected).
In an unrelated if-statement later on, you're correctly getting the TableItem text:
table.getItem(playerIndices[0]).getText();
So instead of using the toString() method on those two lines at the start, you'll want to use getText() as you've done here.

How to hide Selection in JList

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

SWT Table checking box by selecting row or checking the box

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?

Categories

Resources