SWT - How to change the Window Class name? wm_class - java

At present all my Java GUI applications have SWT.SWT as their window class. I would like for some of them to be linked as sub-windows in menu applications such as Cairo-Dock. This is the third column of the out put from wmctrl -lx.
I have tried using the Display.setAppName() method in an attempt to set this name. Neither Display.setAppName or display.SetAppname will change the app class from SWT.SWT to the class name I'm tring to set.
When I use the lower case display.setAppName it produces this warning in the Eclipse IDE:
Description Resource Path Location Type
The static method setAppName(String) from the type Display should be accessed in a static way WBTest.java /javaTools/src/javaTools line 31 Java Problem
Code Sample:
package javaTools;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.wb.swt.SWTResourceManager;
public class WBTest {
private Table table;
/**
* Launch the application.
* #param args
*/
public static void main(String[] args) {
try {
WBTest window = new WBTest();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Open the window.
*/
public void open() {
Display display = Display.getDefault();
display.setAppName("myapplication");
Shell shell = new Shell();
shell.setBackground(SWTResourceManager.getColor(SWT.COLOR_BLACK));
shell.setSize(560, 426);
shell.setText("SWT Application");
table = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION);
table.setBackground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
// table.setBounds(49, 21, 241, 158);
table.setHeaderVisible(true);
table.setLinesVisible(true);
TableItem row = new TableItem(table, SWT.NONE);
row.setText("This is a test.");
shell.open();
// shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
}
My research shows how to do this in Python, which works:
#!/usr/bin/python
from gi.repository import Gtk
win = Gtk.Window()
win.connect("delete-event", Gtk.main_quit)
win.set_wmclass ("Hello World", "Hello World")
win.set_title ("Hello World")
win.show_all()
Gtk.main()
I'm trying to do the same thing with SWT/Java.
Is there something else I need to add to this function to make it work, or is there a differernt function that is specific to setting the application's class name?

I don't know whether to remove this question or provide the answer. I had worked on it since yesterday and was still trying lots of variations.
One finally works. Apparently, the line has to appear in the code before declaring the Display.
This works:
package javaTools;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.wb.swt.SWTResourceManager;
public class WBTest {
private Table table;
/**
* Launch the application.
* #param args
*/
public static void main(String[] args) {
try {
WBTest window = new WBTest();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Open the window.
*/
public void open() {
Display.setAppName("myapplication");
Display display = Display.getDefault();
Display.setAppName("myapplication");
Shell shell = new Shell();
shell.setBackground(SWTResourceManager.getColor(SWT.COLOR_BLACK));
shell.setSize(560, 426);
shell.setText("SWT Application");
table = new Table(shell, SWT.BORDER | SWT.FULL_SELECTION);
table.setBackground(SWTResourceManager.getColor(SWT.COLOR_BLUE));
// table.setBounds(49, 21, 241, 158);
table.setHeaderVisible(true);
table.setLinesVisible(true);
TableItem row = new TableItem(table, SWT.NONE);
row.setText("This is a test.");
shell.open();
// shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
}

Related

JavaSWT app working in Eclipse but not in Terminal

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class clientWindow {
static Text chatWindow;
public static void sendMessage(Socket socket, String message) throws IOException {
PrintWriter pr = new PrintWriter(socket.getOutputStream());
pr.println("Client: " + message);
pr.flush();
}
public static void main(String[] args) throws UnknownHostException, IOException {
Socket s = new Socket("10.0.1.8", 4500);
Display display = new Display();
Shell clientWindow = new Shell(display);
GridLayout layout = new GridLayout();
layout.numColumns = 1;
clientWindow.setLayout(layout);
GridData data = new GridData(GridData.FILL_HORIZONTAL);
GridData data1 = new GridData(GridData.FILL_BOTH);
chatWindow = new Text(clientWindow, SWT.MULTI | SWT.V_SCROLL | SWT.READ_ONLY);
chatWindow.setLayoutData(data1);
Text messageBox = new Text(clientWindow, SWT.SINGLE);
messageBox.setLayoutData(data);
Button send = new Button(clientWindow, 0);
send.setText("Send");
send.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent event) {
try {
sendMessage(s, messageBox.getText());
messageBox.setText("");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void widgetDefaultSelected(SelectionEvent arg0) {
// TODO Auto-generated method stub
}
});
clientWindow.open();
while (!clientWindow.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
}
This is a small messaging app that I've finished. Everything in here works fine in Eclipse. When I try to run it in the Terminal, however, I get this.
Exception in thread "main" org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:4711)
at org.eclipse.swt.SWT.error(SWT.java:4626)
at org.eclipse.swt.SWT.error(SWT.java:4597)
at org.eclipse.swt.widgets.Display.error(Display.java:1112)
at org.eclipse.swt.widgets.Display.createDisplay(Display.java:853)
at org.eclipse.swt.widgets.Display.create(Display.java:837)
at org.eclipse.swt.graphics.Device.<init>(Device.java:132)
at org.eclipse.swt.widgets.Display.<init>(Display.java:736)
at org.eclipse.swt.widgets.Display.<init>(Display.java:727)
at clientWindow.main(clientWindow.java:28)
I'm pretty sure this error happens when a trying to access the Display from something that isn't in "main", which isn't what I'm trying to do. So why is it giving me this error?
Judging by the line numbers in the Display code you are running this on macOS.
On macOS you must specify the -XstartOnFirstThread option when you run your code with the java command in Terminal.
The program works in Eclipse because Eclipse sets this up for you automatically in the Run Configuration.

Evaluate bounds of a Path (created only with a String)

I would like to draw a String with Path and center it inside a Rectangle.
The problem is that I don't know how to evaluate the size/bounds of the path.
I have tried to use the corresponding size of the the same String drawn in a normal way (gc.drawString...) and after using gc.textExtent(String), but apparently the two size are different so the result is not ok....
Do you have any idea how to evaluate the size of the path in order to draw it centered in a rectangle?
The problem is that drawing a string with path is bigger that drawing a string in the normal way. You can verify it with this simple code.
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Path;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
public class ShapeText
{
static Path path=null;
public static void main(String[] args)
{
final Display display = new Display();
Font font = new Font(display, "Times", 50, SWT.BOLD);
final Color blue = display.getSystemColor(SWT.COLOR_BLUE);
final Color red = display.getSystemColor(SWT.COLOR_RED);
try {
} catch (SWTException e) {
System.out.println(e.getMessage());
display.dispose();
return;
}
Shell shell = new Shell(display);
shell.addListener(SWT.Paint, new Listener()
{
public void handleEvent(Event e)
{
path = new Path(display);
e.gc.setFont(font);
path.addString("Path is different", 0, 0, font);
GC gc = e.gc;
gc.setAntialias(SWT.ON);
gc.setTextAntialias(SWT.ON);
gc.setForeground(blue);
gc.setBackground(blue);
//gc.fillPath(path);
gc.drawPath(path);
gc.setForeground(red);
gc.drawString("Path is different", 0, 0,true);
}
});
shell.setSize(530,120);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
path.dispose();
font.dispose();
display.dispose();
}
}
This is the result:
As you can see the String drawn with Path (in blue) is longer than the other (in red)...

Bug when removing columns from Nebula Grid using Visual Range Support

I'm trying to dispose of columns and add new ones to a Nebula Grid, the data in the table won't change I just want to be able to change the columns used.
I am getting a bug where the Grid is throwing index out of bounds exceptions as it's iterating through a list of existing columns but using a value "endColumnIndex" to stop the loop, but the endColumnIndex value is bigger than the list of new columns.
I believe this is due to using Visual Range Support, and the value for the current on screen columns is not being updated as I am removing them.
I have written a class to reproduce this bug here, and am hoping someone has a workaround for this issue:
import org.eclipse.nebula.jface.gridviewer.GridTableViewer;
import org.eclipse.nebula.jface.gridviewer.GridViewerColumn;
import org.eclipse.nebula.widgets.grid.GridColumn;
import org.eclipse.nebula.widgets.grid.GridItem;
import org.eclipse.nebula.widgets.grid.GridVisibleRangeSupport;
import org.eclipse.nebula.widgets.grid.GridVisibleRangeSupport.RangeChangedEvent;
import org.eclipse.nebula.widgets.grid.GridVisibleRangeSupport.VisibleRangeChangedListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class GridRangeChangeBug {
public static void main(String[] args) {
Display display = new Display();
final Shell shell = new Shell(display);
shell.setSize(800, 800);
shell.setLayout(new GridLayout(1, true));
Button go = new Button(shell, SWT.PUSH);
go.setText("Reproduce Bug");
final GridTableViewer viewer = new GridTableViewer(shell, SWT.H_SCROLL
| SWT.V_SCROLL | SWT.BORDER);
viewer.getGrid().setLayoutData(
new GridData(SWT.FILL, SWT.FILL, true, true));
viewer.getGrid().setHeaderVisible(true);
GridVisibleRangeSupport rangeSupport = GridVisibleRangeSupport.createFor(viewer.getGrid());
rangeSupport.addRangeChangeListener(new VisibleRangeChangedListener() {
#Override
public void rangeChanged(RangeChangedEvent event) {
}
});
for (int i = 0; i < 100; i++) {
GridViewerColumn col = new GridViewerColumn(viewer, SWT.NONE);
col.getColumn().setWidth(30);
col.getColumn().setText("" + i);
}
go.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
for (GridColumn c : viewer.getGrid().getColumns()) {
c.dispose();
}
for (int i = 0; i < 10; i++) {
GridViewerColumn col = new GridViewerColumn(viewer,
SWT.NONE);
col.getColumn().setWidth(30);
col.getColumn().setText("" + i);
}
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}

Get input field of a dialog in eclipse

For my plugin, I try to get the active Eclipse dialog with these lines:
String shellTitle = Display.getCurrent().getActiveShell().getTitle();
System.out.println("Opened dialog: " + shellTitle);
If e.g. I open the search dialog, these lines print me
Opened dialog: Search
in my console. But I would also want to print the keyword in the search field, for example
Opened dialog: Search (with the search word 'ChatSession')
I have read the API reference and there, I just can found the getTitle() and some other methods for getting bounds and so on.
Is my idea realizable? And if not, is it realizable with these so-called extension points? I have never used them but heard of them.
Mistakes in your question:
You are calling getTitle() method on Shell array object. It is wrong.
You are mixing dialog and Shell
Assuming you are talking about Shell. You can use the below code to get the controls on active Shell.
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class ShellControlsGetting {
public static void main(String[] args) {
Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
Button button = new Button(shell, SWT.PUSH);
button.setText("Open 3 Shells");
final Shell[] shells = new Shell[3];
button.addSelectionListener(new SelectionListener() {
#Override
public void widgetSelected(SelectionEvent e) {
for (int i = 0; i < 3; i++) {
shells[i] = new Shell(shell);
shells[i].setText("Shell" + (i + 1));
shells[i].setLayout(new FillLayout());
shells[i].setSize(250, 50);
shells[i].setLocation(100, 200 + (i + 1) * 100);
Label label = new Label(shells[i], SWT.LEFT);
label.setText("Search Box" + (i + 1));
Text search = new Text(shells[i], SWT.SINGLE | SWT.BORDER);
search.setText("search key" + (i + 1));
shells[i].open();
}
Shell currentActiveShell = Display.getCurrent().getActiveShell();
String shellTitle = currentActiveShell.getText();
Control[] children = currentActiveShell.getChildren();
for (int i = 0; i < children.length; i++) {
Control child = children[i];
if (child instanceof Text) {
System.out.println("Opened dialog: " + shellTitle + "(with the search word '" + ((Text)child).getText()
+ "')");
}
}
}
#Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
If this not answers you question then edit your post add some code and clarify what exactly you are expecting.

swt table has limitation on text length in a cell?

I use JFace TableViewer and databinding to display data of a database table, some columns have very long text, I found the text is cut out. if I activate the text editor associated with that cell, I can see the full text.
Does swt table has limitation on text length in a cell ? or the OS has such limitation ?(I am using eclipse 3.6 and windows 7 32 bit)
/*******************************************************************************
* Copyright (c) 2006 Tom Schindl and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Tom Schindl - initial API and implementation
*******************************************************************************/
package org.eclipse.jface.snippets.viewers;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
/**
* A simple TableViewer to demonstrate usage
*
* #author Tom Schindl <tom.schindl#bestsolution.at>
*
*/
public class Snippet001TableViewer {
private class MyContentProvider implements IStructuredContentProvider {
/* (non-Javadoc)
* #see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
*/
public Object[] getElements(Object inputElement) {
return (MyModel[])inputElement;
}
/* (non-Javadoc)
* #see org.eclipse.jface.viewers.IContentProvider#dispose()
*/
public void dispose() {
}
/* (non-Javadoc)
* #see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
*/
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
public class MyModel {
public int counter;
public MyModel(int counter) {
this.counter = counter;
}
public String toString() {
**return "very loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooog text" + this.counter;**
}
}
public Snippet001TableViewer(Shell shell) {
final TableViewer v = new TableViewer(shell);
v.setLabelProvider(new LabelProvider());
v.setContentProvider(new MyContentProvider());
MyModel[] model = createModel();
v.setInput(model);
v.getTable().setLinesVisible(true);
}
private MyModel[] createModel() {
MyModel[] elements = new MyModel[10];
for( int i = 0; i < 10; i++ ) {
elements[i] = new MyModel(i);
}
return elements;
}
/**
* #param args
*/
public static void main(String[] args) {
Display display = new Display ();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
new Snippet001TableViewer(shell);
shell.open ();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
}
It's windows bug/feature (see bugzilla for details), here is the proof (linux screenshot of your code)
I may be possible to workaround this bug/feature by self cell rendering (see Custom Drawing Table and Tree Items tutorial).
I found a simple way to get the whole text shown.
You have to use a StyledCellLabelProvider and override the update-method.
Here is a little example which shows the differences between a StyledCellLabelProvider and a ColumnLabelProvider. To override the update-method of ColumnLabelProvider is unnecessary. I did it to show that it depends on the class.
package tabletest;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableColumn;
public class MyClass {
private static final String LINE = "123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J"// 100
+ "123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789S123456789T" // 200
+ "123456789U123456789V123456789W123456789X123456789Y123456789Z" // 260
+ " a lot mor text";
public MyClass(Shell shell){
createControl(shell);
}
private void createControl(Composite parent){
parent.setLayout(new GridLayout(1, true));
TableViewer viewer = new TableViewer(parent, SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL |SWT.H_SCROLL);
viewer.getTable().setHeaderVisible(true);
viewer.getTable().setLinesVisible(true);
viewer.setContentProvider(ArrayContentProvider.getInstance());
viewer.setLabelProvider(new LabelProvider());
createColumn(viewer);
viewer.setInput(new String[] { LINE });
for(TableColumn col : viewer.getTable().getColumns()){
col.pack();
}
GridDataFactory.fillDefaults().grab(true, true).applyTo(viewer.getControl());
}
private void createColumn(TableViewer viewer) {
TableViewerColumn column1 = new TableViewerColumn(viewer, SWT.NONE);
column1.getColumn().setText("ColumnLabelProvider");
column1.setLabelProvider(new ColumnLabelProvider(){
#Override
public void update(ViewerCell cell) {
cell.setText(cell.getElement().toString());
super.update(cell);
}
});
TableViewerColumn column2 = new TableViewerColumn(viewer, SWT.NONE);
column2.getColumn().setText("StyledCellLabelProvider");
column2.setLabelProvider(new StyledCellLabelProvider() {
#Override
public void update(ViewerCell cell) {
cell.setText(cell.getElement().toString());
super.update(cell);
}
});
}
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
new MyClass(shell);
shell.open();
while(!shell.isDisposed()){
if(!display.readAndDispatch()){
display.sleep();
}
}
}
}
It also works in the Snippet001TableViewer when you change the LabelProvider to a StyledCellLabelProvider and override the update-method similar to my example.

Categories