I am trying to write a simple app that create a transparent overlay over the full screen and draw a line at my current mouse position. This line should then follow my mouse movements until mouse press when the app is to exit.
I currently have an issue with redraw in the app that will not work and I guess that I have missplaced and/or missunderstood how the redraw should be used.
How to redraw an application like this correctly and resource efficient?
Sample code:
public class TAGuideLine {
static Display display = new Display();
static Shell shell = new Shell(display, SWT.NO_TRIM | SWT.ON_TOP);
public static void main(String[] args) {
shell.setBackground(display.getSystemColor(SWT.COLOR_RED));
shell.setMaximized(true);
shell.setFullScreen(true);
shell.setLayoutData(0);
shell.layout(true, true);
shell.setAlpha(50);
shell.addListener(SWT.MouseDown, new Listener() {
public void handleEvent(Event e) {
System.exit(0);
}
});
shell.addListener(SWT.MouseMove, new Listener() {
public void handleEvent(Event e) {
drawMyLine(MouseInfo.getPointerInfo().getLocation().x,
MouseInfo.getPointerInfo().getLocation().y);
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
shell.redraw();
shell.layout();
display.dispose();
}
public static void drawMyLine(int x, int y) {
final GC gc = new GC(shell);
gc.setForeground(display.getSystemColor(SWT.COLOR_GREEN));
gc.setLineWidth(8);
gc.drawLine(x - 250, y - 250, x + 250, y + 250);
gc.dispose();
shell.open();
}
}
To draw on a Shell you usually add a paint listener that does the actual drawing. The mouse event listener would just store the coordinates to draw and then trigger a redraw on the shell.
Below is a sketch of what the code could look like:
List<Point> points = new ArrayList<>();
shell.addListener( SWT.Paint, new Listener() {
public void handleEvent( Event event ) {
event.gc.setForeground( display.getSystemColor( SWT.COLOR_GREEN ) );
event.gc.setLineWidth( 8 );
for( Point point : points ) {
event.gc.drawLine( point.x - 250, point.y - 250, point.x + 250, point.y + 250 );
}
} );
shell.addListener( SWT.MouseMove, new Listener() {
public void handleEvent( Event event ) {
points.add( MouseInfo.getPointerInfo().getLocation() );
shell.redraw();
}
} );
Class GC also has a drawPolyLine() method that might be more suitable for this use case.
Unrelated to your question but still: a more graceful way to exit the application is to dispose of the Shell with shell.dispose()instead of calling System.exit().
Related
I have a code that has a JLabel which follows the mouse. The JLabel says "exit" whenever the user exits the window, and stays at the last position the user was in. The problem is, the "exit" is only visible at when exiting the window from the top. This is because the JLabel is under the mouse. I want to make it so that the label moves down so I can see it if it exits up and move up if it exits down. I understand how to move it, but can we move it based on conditions? It shows up in the window fine, I just need to position it on different sides of my mouse based on exit position.
Here is my code:
class giraffemousehandler extends MouseAdapter implements MouseListener, MouseMotionListener { //MouseAdapter makes it so that you don't have to have all 7 implemented mouse listener methods
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
status.setBounds(e.getX(), e.getY(), 50, 60); //Makes JLabel follow mouse
}
#Override
public void mouseEntered(MouseEvent e) {
status.setText("Entered");
}
#Override
public void mouseExited(MouseEvent e) {
status.setText("exited");
// status.setBounds(e.getX(), e.getY(), 5, 6);
}
}
}
Thank you so much for the time you are taking for reading this, I really appreciate the effort you are putting into helping a fellow programmer!
public class GiraffeMouseHandler extends MouseAdapter implements MouseMotionListener
{
public void mouseEntered( MouseEvent event )
{
status.setText( "Entered" );
}
public void mouseExited( MouseEvent event )
{
status.setText( "Exited" );
}
public void mouseMoved( MouseEvent event )
{
//dimension is a reference of dimension of the main frame
if( ( dimension.getHeight() - event.getY() ) < 65 )
status.setBounds( event.getX(), (int)dimension.getHeight() - 65 , 50, 60 );
else if( ( dimension.getWidth() - event.getX() ) < 50 )
status.setBounds( (int)dimension.getWidth() - 50, event.getY(), 50, 60 );
else
status.setBounds( event.getX(), event.getY(), 50, 60 );
}
}
I try to make scroll working and I also want to auto resize window and content that is in the window. My interface is going to have couple of composite blocks that are going to parse some information, and fields inside block are static and they going to be always same fields in same block `
public void open() {
Display display = Display.getDefault();
createContents();
shell.addListener (SWT.Resize, new Listener () {
public void handleEvent (Event e) {
Rectangle rect = shell.getClientArea ();
System.out.println(rect);
}
});
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
/**
* Create contents of the window.
*/
protected void createContents() {
shell = new Shell(SWT.SHELL_TRIM |SWT.V_SCROLL | SWT.H_SCROLL);
shell.addMouseWheelListener(new MouseWheelListener() {
public void mouseScrolled(MouseEvent e) {
}
});
shell.setSize(1546, 878);
shell.setBackground(SWTResourceManager.getColor(255, 255, 255));
shell.setMaximized(true);
shell.setMinimumSize(1500, 600);
shell.setText("Test App for nothing");
shell.setLayout(new FillLayout(SWT.HORIZONTAL));
I want to add a KeyListener to my existing window. I want to catch 3 KeyDown's. On the first KeyDown I want to put something in a Combo. On the second KeyDown I want to put something in another Combo. If both textbox are filled, I want the next KeyDown to simulate the OK Button.
But I have a problem with the error widget disposed. Because I dont know when to remove the filter correct. This only happend if I open the window again!
My Code:
_disp.addFilter(SWT.KeyDown, new Listener() {
public void handleEvent(Event e) {
if(!_disp.isDisposed()){
_disp.removeFilter(SWT.KeyDown, this);
}
if (e.keyCode == SWT.CR) {
if (_cmbCCID.getText().isEmpty()) {
_cmbCCID.setText(_lastFiveCCID[0]);
} else if (_cmbDescription.getText().isEmpty()) {
_cmbDescription.setText(_lastFiveComment[0]);
} else if (!_cmbCCID.getText().isEmpty() && !_cmbDescription.getText().isEmpty()) {
_btnOk.notifyListeners(SWT.Selection, new Event());
}
}
}
});
You're removing the filter after the first key press. Try something like this:
public static void main(String[] args)
{
final Display display = new Display();
Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new FillLayout());
new Text(shell, SWT.NONE);
display.addFilter(SWT.KeyDown, new Listener()
{
int i = 0;
#Override
public void handleEvent(Event arg0)
{
if (i < 2)
System.out.println("Press " + i);
else
{
System.out.println("Press " + i);
System.out.println("Remove");
if (!display.isDisposed())
display.removeFilter(SWT.KeyDown, this);
}
i++;
}
});
shell.pack();
shell.open();
while (!shell.isDisposed())
{
while (!display.readAndDispatch())
{
display.sleep();
}
}
}
It will remove the filter after the third key press event.
I am working with SWT and I would like to be able to resize a composite by dragging the corner of it, the same way that you can resize a shell. I'm sure someone out there has implemented a good solution. Thanks.
I think what you are looking for can be implemented with org.eclipse.swt.widgets.Tracker
here is sample working code:
public static void main(String[] args) {
Display display = new Display();
final Shell shell = new Shell(display);
shell.open();
final Composite b = new Composite(shell, SWT.NONE);
b.setBounds(20, 20, 80, 80);
b.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
b.addListener(SWT.MouseDown, new Listener() {
public void handleEvent(Event e) {
Tracker tracker = new Tracker(b.getParent(), SWT.RESIZE);
tracker.setStippled(true);
Rectangle rect = b.getBounds();
tracker.setRectangles(new Rectangle[] { rect });
if (tracker.open()) {
Rectangle after = tracker.getRectangles()[0];
b.setBounds(after);
}
tracker.dispose();
}
});
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
My try as follows,which doesn't come up with anything:
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
Image image = new Image(display,
"D:/topic.png");
GC gc = new GC(image);
gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
gc.drawText("I've been drawn on",0,0,true);
gc.dispose();
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
// TODO Auto-generated method stub
}
See the SWT-Snippets for examples. This one uses an image label
Shell shell = new Shell (display);
Label label = new Label (shell, SWT.BORDER);
label.setImage (image);
You are missing one thing in your code. Event Handler for paint. Normally when you create a component it generates a paint event. All the drawing related stuff should go in it.
Also you need not to create the GC explicitly.. It comes with the event object :)
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class ImageX
{
public static void main (String [] args)
{
Display display = new Display ();
Shell shell = new Shell (display, SWT.SHELL_TRIM | SWT.DOUBLE_BUFFERED);
shell.setLayout(new FillLayout ());
final Image image = new Image(display, "C:\\temp\\flyimage1.png");
shell.addListener (SWT.Paint, new Listener ()
{
public void handleEvent (Event e) {
GC gc = e.gc;
int x = 10, y = 10;
gc.drawImage (image, x, y);
gc.dispose();
}
});
shell.setSize (600, 400);
shell.open ();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ())
display.sleep ();
}
if(image != null && !image.isDisposed())
image.dispose();
display.dispose ();
}
}