Java Table weirdness on Mac - java

I am developing an Eclipse plugin that uses Table to print out to a view. I tested the system on various Eclipse and Ubuntu versions and the values in the table are visible. i.e. rows fit the content. But when deploying it to Mac, the rows do not fit the content. I can see that something is inside but the whole content is not visible nor I can resize it. Here is the code I am using:
int style = SWT.NONE;
Table table = new Table(composite, style);
table.setHeaderVisible(true);
table.setLinesVisible(true);
TableColumn col = new TableColumn(table, style);
// Is this ok?
col.setWidth(200);
col.setResizable(true);
for (int i = 0; i < contents.size(); i++){
TableItem item = new TableItem(table, style);
item.setText(contents.get(i));
}
I tried with different styles but no luck. Any idea what is going wrong?

Ok, I came up with this piece of code that does the trick:
public class TableItemPaintListener implements Listener{
public void handleEvent(Event event) {
switch (event.type) {
case SWT.MeasureItem: {
TableItem item = (TableItem) event.item;
String text = item.getText();
Point size = event.gc.textExtent(text);
event.width = size.x;
event.height = Math.max(event.height, size.y);
break;
}
}
}
}
and then:
table.addListener(SWT.MeasureItem, new TableItemPaintListener());
Basically, we install a handler on a paint event that is triggered on each table item. Then, we set the cell height value to fit the content.

Related

JTable not able to set header background color

Created a table to show reports, everything else is working but I am not able to set the header background color. I have tried changing the setOpaque() and another thing I would like to avoid using custom renderer for the problem.
My code for creating the table is as follows.
private void showTable() {
if (alUserRecord != null) {
String heading[] = {"Username", "Groupname", "Groupstatus"};
String data[][] = new String[alUserRecord.size()][heading.length];
for (int i = 0; i < alUserRecord.size(); i++) {
GroupManageBean objbean = alUserRecord.get(i);
data[i][0] = objbean.getUsername();
data[i][1] = objbean.getGroupname();
if (objbean.isGroupstatus()) {
data[i][2] = "Active";
} else {
data[i][2] = "Inactive";
}
}
tblUserReport = new JTable(data, heading);
jScrollPane1.setViewportView(tblUserReport);
tblUserReport.setFillsViewportHeight(true);
tblUserReport.setBackground(new Color(161,158,152));
tblUserReport.setBorder(new LineBorder(new Color(0,102,102), 2, true));
tblUserReport.getTableHeader().setBackground(new Color(0,102,102));
tblUserReport.getTableHeader().setForeground(Color.WHITE);
}
}
In the above code alUserRecord is an ArrayList that gets its values from another method that fetches the data from MySQL database. By the way every line in this code is working except tblUserReport.getTableHeader().setBackground......
Can anyone please help me with that?

JavaFX TableView Click on Header

Is there a way to get an mouse-click on an Header of a Table?
Why i need this?
I have a Table with many Columns. But only a specific witdth for the whole Table.
To avoid scrolling, i want to give each Column an specific width (50 or so), and just if you click on an header, this column will expand so you can read the content. If you click on another header, the previous one collapse.
Hopefully someone can help me:)
Unfortunately there isn't a nice way to do this. The only public API option is to replace the "graphic" of the column with your own label, and then add a mouse listener to that. For this to work you also need to clear any existing column text.
Note that columns by default have click listeners to implement sorting, it seems you don't want this behaviour, so you'll also need to call column.setSortable(false)
#Override
public void start(Stage primaryStage) throws Exception {
TableView<String> tableView = new TableView<>();
TableColumn<String, Object> x = new TableColumn<>("x");
tableView.getColumns().add(x);
TableColumn<String, Object> y = new TableColumn<>("");
tableView.getColumns().add(y);
x.setSortable(false);
y.setSortable(false);
makeHeader(x, "X", 0);
makeHeader(y, "Y", 1);
EventHandler<? super MouseEvent> handler = event -> {
System.out.println("Column clicked " + ((Node)event.getTarget()).getProperties().get("index"));
};
x.getGraphic().addEventFilter(MouseEvent.MOUSE_CLICKED, handler);
y.getGraphic().addEventFilter(MouseEvent.MOUSE_CLICKED, handler);
primaryStage.setScene(new Scene(tableView));
primaryStage.show();
}
private void makeHeader(TableColumn<?, ?> target, String name, int index) {
VBox vBox = new VBox(new Label(name));
vBox.setAlignment(Pos.CENTER);
vBox.getProperties().put("index", index);
target.setGraphic(vBox);
target.setText("");
}
// Step 0: call setOnShown(...).
stage.setOnShown(event -> {
setHeaderClickListeners(); // Call this method when the stage is shown.
});
And then you create a method setHeaderClickListeners(), as follows:
private void setHeaderClickListeners() {
// Step 1: Get the table header row.
TableHeaderRow headerRow = null;
for (Node n : ((TableViewSkin<?>) tableView.getSkin()).getChildren()) {
if (n instanceof TableHeaderRow) {
headerRow = (TableHeaderRow) n;
}
}
if (headerRow == null) {
return;
}
// Step 2: Get the list of the header columns.
NestedTableColumnHeader ntch = (NestedTableColumnHeader) headerRow.getChildren().get(1);
ObservableList<TableColumnHeader> headers = ntch.getColumnHeaders();
// Step 3: Add click listener to the header columns.
for (int i = 0; i < headers.size(); i++) {
TableColumnHeader header = headers.get(i);
final int index = i;
header.setOnMouseClicked(mouseEvent -> {
// Optional:
// Get the TableColumnBase (which is the object responsible
// for displaying the content of the column.)
TableColumnBase column = header.getTableColumn();
// Step 4: Handle double mouse click event.
if (mouseEvent.getButton() == MouseButton.PRIMARY && mouseEvent.getClickCount() == 2) {
P.x("Header cell " + index + " clicked! " + column.getText());
}
});
}
}

Must click the next Text Widget to save the previous text content

I used SWT to create a table, and in this table's forth column need to be editable, so I used TableEditor to make it. However every time I need to click the next Widget Text to save the content of previous text content. For example: in my table the forth column can be editable,
I fill number in the first row forth column, I need to click the second row forth column, and only do this the content of Text of first row forth column can be saved.why? Follow is my
code:
final TableEditor editor=new TableEditor(table);
editor.horizontalAlignment=SWT.LEFT;
editor.grabHorizontal=true;
final int EDITABLECOLUMN=3;
table.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
// Clean up any previous editor control
Control oldEditor = editor.getEditor();
if (oldEditor != null)
oldEditor.dispose();
// Identify the selected row
TableItem item = (TableItem) e.item;
if (item == null)
return;
// The control that will be the editor must be a child of the
// Table
Text newEditor = new Text(table, SWT.NONE);
newEditor.setText(item.getText(EDITABLECOLUMN));
newEditor.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent me) {
Text text = (Text) editor.getEditor();
editor.getItem().setText(EDITABLECOLUMN, text.getText());
}
});
newEditor.selectAll();
newEditor.setFocus();
editor.setEditor(newEditor, item, EDITABLECOLUMN);
}
});
and my table created in this way:
public Table createTable(Composite parent){
//表格布局
GridData gridData=new GridData();
gridData.horizontalAlignment=SWT.FILL;
gridData.grabExcessHorizontalSpace=true;
gridData.grabExcessVerticalSpace=true;
gridData.verticalAlignment=SWT.FILL;
//创建表格,及其格式
final Table table=new Table(parent,SWT.CHECK|SWT.MULTI|SWT.FULL_SELECTION|SWT.V_SCROLL|SWT.H_SCROLL);
table.setHeaderVisible(true);
table.setLayoutData(gridData);
table.setLinesVisible(true);
//创建表头
String[] tableHeader={"Num","Package","Class","Run Times"};
int[] tableColumnWidth={100,150,400,80};
for(int i=0;i<tableHeader.length;i++){
TableColumn tableColumn=new TableColumn(table,SWT.NONE|SWT.CENTER);
tableColumn.setText(tableHeader[i]);
tableColumn.setMoveable(true);
tableColumn.setWidth(tableColumnWidth[i]);
}
table.addListener(SWT.Selection, tableListener);
return table;
}
I changed the content of area where was marked as number one, this content only saved when I clicked area 2. It means only clicking area 2 to active the event:

SWT Table with date chooser fields

This is an obvious question but for some reason I haven't found a solution that works. I have a table with 3 columns, the first two are dates, the third one I'm using a Spinner because I want the user to only enter numbers. I need all fields to be editable, but
the field should be editable only when it's in focus, when it's clicked on
the other fields in the same row should not be editable
when the field loses focus, it should go back to "default" mode
These are all normal things that one would expect in an editable table. For some reason I couldn't make this work in SWT. Right now what I have is:
I add a new row, all fields are "default"
I click on the row, all fields turn into editable (the date fields become combo boxes etc.)
after the row losing focus, it remains editable
This is the code that I have right now, it's based on some other code I found on the internet:
// this will happen when you click on the table
table.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Clean up any previous editor control
final TableEditor editor1 = new TableEditor(table);
// The editor must have the same size as the cell and must
// not be any smaller than 50 pixels.
editor1.horizontalAlignment = SWT.LEFT;
editor1.grabHorizontal = true;
editor1.minimumWidth = 50;
Control oldEditor = editor1.getEditor();
if (oldEditor != null)
oldEditor.dispose();
// Identify the selected row
TableItem item = (TableItem)e.item;
if (item == null) return;
// this is the editor for the first column
DateTime startDateTxt = new DateTime(table, SWT.BORDER | SWT.DROP_DOWN | SWT.LONG);
startDateTxt.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
DateTime text = (DateTime)editor1.getEditor();
editor1.getItem().setText(0, new LocalDate(text.getYear(), text.getMonth(), text.getDay()).toString());
}
});
editor1.setEditor(startDateTxt, item, 0);
// and now comes the editor for the 2nd column
//~~~~
// Clean up any previous editor control
final TableEditor editor2 = new TableEditor(table);
// The editor must have the same size as the cell and must
// not be any smaller than 50 pixels.
editor2.horizontalAlignment = SWT.LEFT;
editor2.grabHorizontal = true;
editor2.minimumWidth = 50;
oldEditor = editor2.getEditor();
if (oldEditor != null)
oldEditor.dispose();
// this is the editor for the second column
DateTime endDateTxt = new DateTime(table, SWT.BORDER | SWT.DROP_DOWN | SWT.LONG);
endDateTxt.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
DateTime text = (DateTime)editor2.getEditor();
editor2.getItem().setText(1, new LocalDate(text.getYear(), text.getMonth(), text.getDay()).toString());
}
});
editor2.setEditor(endDateTxt, item, 1);
//~~~~
// Clean up any previous editor control
final TableEditor editor3 = new TableEditor(table);
// The editor must have the same size as the cell and must
// not be any smaller than 50 pixels.
editor3.horizontalAlignment = SWT.LEFT;
editor3.grabHorizontal = true;
editor3.minimumWidth = 50;
oldEditor = editor3.getEditor();
if (oldEditor != null)
oldEditor.dispose();
// this is the editor for the third column
Spinner percentTxt = createNewSpinner(table, SWT.NONE);
percentTxt.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent me) {
Spinner text = (Spinner)editor3.getEditor();
editor3.getItem().setText(2, text.getText());
}
});
editor3.setEditor(percentTxt, item, 2);
//~~~~
}
});
As you can see, when the user clicks on the table, I get the current row, and add 3 editors to the row. What I would like to do is get the selected column. I haven't found how to do this. If I get the selected column, then I would be able to create an editor just for the selected cell, and not the whole row.
I also haven't figured out how to dispose the editor after it loses focus. If the user clicks outside the table, then it has clearly happened. But what if the user just clicks on another cell? Then I would have to dispose the old editor and create a new one.
To get the selected column you can call TableItem.getBounds(columnIndex) for each column and see if the selection is within the rectangle returned.

How to get the text content on the swt table with arbitrary controls

I have different controls placed on a table using TableEditor.
...
TableItem [] items = table.getItems ();
for (int i=0; i<items.length; i++) {
TableEditor editor = new TableEditor (table);
final Text text1 = new Text (table, SWT.NONE);
text1.setText(listSimOnlyComponents.get(i).getName());
text1.setEditable(false);
editor.grabHorizontal = true;
editor.setEditor(text1, items[i], 0);
editor = new TableEditor (table);
final CCombo combo1 = new CCombo (table, SWT.NONE);
combo1.setText("");
Set<String> comps = mapComponentToPort.keySet();
for(String comp:comps)
combo1.add(comp);
editor.grabHorizontal = true;
editor.setEditor(combo1, items[i], 1);
} //end of for
...
When I try to get the text on the table using getItem(i).getText, I get empty string
...
TableItem [] items = table.getItems ();
for(int i=0; i<items.length; i++) {
TableItem item = items[i];
String col0text = items[i].getText(0); //this text is empty
String col1text = items[i].getText(1); //this text is empty
}
...
Why does getText returns empty strings even when I have text appearing on the table?
Instead of using the text property, you might consider using the data property instead.
Benefits:
you can attach the data (e.g. a control or complex data structure) directly to the table item.
the only thing your table item creation need to know from your table cell editor is the object reference to be stored in the data property.
you don't need that event handling stuff (just read the controls data when you really need it).
Create:
TableItem item = new TableItem(table, SWT.None);
TableEditor editor = new TableEditor(table);
Button checkbox = new Button(table, SWT.CHECK);
checkbox.pack();
editor.setEditor(checkbox,item,0);
item.setData("cb",checkbox); // using key enables you to add more pieces of complex data
Read:
for (TableItem item : table) {
Button checkbox = (Button) item.getData("cb");
if (checkbox.getSelection()) { /* ... do whatever you want */ }
}
When the table shows up, the checkbox is visible and can be clicked. Using the setText method fails in case of transparent background controls -> you will see the text of the table items cell below
your control (I tried this).
Anyway it would be much easier if it would be possible to extend the table item class to hide even the data key. But as usual, subclassing is denied.
in the event listeners for the controls I added
item.setText call
...
combo1.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent evt) {
String sel = combo2.getText();
item.setText(ComponentPortToConnectCol, sel);
}});
...
This gives me the desired result. Thanks OTisler for the clue
How are you setting up your table? I copied your code to debug it and set up the table as shown below (first for loop)
I tried but couldn't reproduce the problem you're seeing. It might be the way you are adding things to the table.
TableEditor Examples
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
final Table table = new Table(shell, SWT.BORDER | SWT.MULTI);
for (int i = 0; i < 3; i++) {
TableItem item = new TableItem(table, SWT.NONE);
item.setText(new String[] { "" + i, "" + i, "" + i });
}
TableItem [] items = table.getItems();
for (int i=0; i<items.length; i++) {
TableEditor editor = new TableEditor (table);
final Text text1 = new Text (table, SWT.NONE);
text1.setText("TEST");
text1.setEditable(false);
editor.grabHorizontal = true;
editor.setEditor(text1, items[i], 0);
editor = new TableEditor (table);
final CCombo combo1 = new CCombo (table, SWT.NONE);
combo1.setText("");
String[] comps = {"A","B","C"};
for(String comp:comps)
combo1.add(comp);
editor.grabHorizontal = true;
editor.setEditor(combo1, items[i], 1);
} //end of for
TableItem [] items2 = table.getItems ();
for(int i=0; i<items2.length; i++) {
TableItem item = items2[i];
String col0text = items2[i].getText(0); //returns '0' first for loop
}

Categories

Resources