SWT: Change style of a Shell at runtime - java

Is there a way to change the style of a Shell at runtime?
I would like to have a shell not resizable but capable to fill, with its content, the whole screen, when it's in fullscreen. Is there a way to accomplish that?
In other words, when a Shell is not resizable and it has for example a Background Image I get this in full screen :
On the other hand when the Shell is resizable and I go in full screen I get this:
So would like to obtain the second effect but with a not resizable Shell.
Any help would be appreciated.

Following Stefan's comment, I was able to do it listening to the resize event and checking the fullscreen flag, resizing appropriately the shell's size to the monitor size when it's in full screen and to normal size when is not. Here the code that does the trick:
shell.addListener(SWT.Resize, new Listener() {
#Override
public void handleEvent(Event arg0) {
if (shell.getFullScreen()) {
Rectangle r = getMonitorSize(shell);
shell.setSize(r.width, r.height);
shell.redraw();
} else {
shell.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
shell.redraw();
}
}
});

Related

Detect horizontal scrolling in Eclipse plugin

I've written an Eclipse plugin that adds a second SourceViewer beside the standard Python editor window. I can detect when either window is scrolled vertically as follows:
displayViewer = new SourceViewer(liveDisplay, ruler, styles);
displayViewer.addViewportListener(new IViewportListener() {
#Override
public void viewportChanged(int verticalOffset) {
// respond to scroll event
}
});
Is there any equivalent to detect horizontal scrolling? I tried adding a control listener, but that doesn't detect scroll events.

Setting a JFrame without overlapping with taskbar

I need to have a undecorated JFrame(setUndecorated(true)) which need to be shown fullscreen, without overlapping with the taskbar.
I have tried the below solutions.
Calling setExtendedState(MAXIMIZED_BOTH).
Advantage:
This works fine as expected, i.e., the window is getting adjusted itself dynamically, except it has the below issues.
Issues
Initially the window occupies the fullscreen
Though the frame get adjusted itself dynamically, it overlaps with the taskbar.
Tried the below solution as stated in Does JFrame.setExtendedState(MAXIMIZED_BOTH) work with undecorated frames?
GraphicsConfiguration config = aFrame.getGraphicsConfiguration();
Rectangle usableBounds = SunGraphicsEnvironment.getUsableBounds(config.getDevice());
aFrame.setBounds(0, 0, usableBounds.width, usableBounds.height);
Advantage:
I am not getting overlaps and window looks fine.
Issue:
Window is not adjusting itself dynamically when the taskbar position/size is changed.
Any help would be greatly appreciated.
I thought of a design. But not sure about its feasibility. I can use the setBounds(). But then I need my frame to be notified when the task bar is adjusted or repositioned. Is there a way?
Able to able to fix the above issue with the below code,
Rectangle usableBounds = SunGraphicsEnvironment.getUsableBounds(config.getDevice());
setMaximizedBounds(usableBounds);
setExtendedState(MAXIMIZED_BOTH);
So by getUsableBounds I am able to get the bounds leaving the taskbar. And hence I am using setExtendedState(MAXIMIZED_BOTH) the window is getting updated automatically when I re-size/re-position the taskbar. :-)
final Point x = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
Have a separate thread to check whether taskbar get changed. If so update size
new Thread(new Runnable() {
#Override
public void run() {
if (x.equals(GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint())) {
Rectangle r = GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
setSize(r.getSize());
}
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
}).start();

I forget to stop a gui program and run it again. Now I can't close the first program without killing eclipse

I am working on a simple GUI app that just draws some graphics on a canvas. The environment is Vista 64. When I run the program, the Windows resize and minimize buttons work, but the close button doesn't. So I have to press the stop button in Eclipse to kill the program.
But sometimes I forget to press stop, and run the program again. The first instance gets stuck and I can't get rid of it without closing Eclipse. If I get careless I can end up with several java windows I can't close. Is there a way to get control of and close the windows? Also, why does the close button not work?
I doubt the code matters in this case but here it is:
import java.awt.*;
public class RobotFace extends Canvas{
/**
* #param args
*/
public static void main(String[] args) {
RobotFace c = new RobotFace();
c.setBackground(Color.white);
c.setSize(350, 350);
Frame f = new Frame();
f.add(c);
f.setLayout(new FlowLayout());
f.setSize(350,350);
f.setVisible(true);
}
public void paint(Graphics g){
g.setColor(Color.black);
int width = 150;
int height = 200;
g.drawRect((getWidth()-width)/2, (getHeight()-height)/2, width, height);
g.setColor(Color.gray);
g.fillRect((getWidth()-width)/2, (getHeight()-height)/2, width, height);
g.setColor(Color.white);
g.fillRect((getWidth()-80)/2, (getHeight()+50)/2, 80, 20);
g.setColor(Color.yellow);
g.fillOval((getWidth()-105)/2, (getHeight()-100)/2, 30, 30);
g.fillOval((getWidth()+45)/2, (getHeight()-100)/2, 30, 30);
}
}
You can also kill it using the console of eclips , there is a red button(right cornor) when you open console view in eclips.
To open console view
Window --> Show View --> Console
using this way you can close the Frame/window
//add window event adapter
f.addWindowListener(new MyWindowAdapter());
class MyWindowAdapter extends WindowAdapter{
MyWindowAdapter(){
}
//implement windowClosing method
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
Your Eclipse console for the first application instance should still be available, just not visible. On the Console tab, you can click the toolbar button that looks like a little blue monitor to switch between application instances. To stop the first application instance, you would select that instance using the little blue monitor (it's called "Display Selected Console"), then click the "Stop" button.
One option is to change the behavior of your program so that it actually exits with the window is close (which is not the default behavior or Frames in Java.
The Frame javadoc specifies that it can generate WindowClosing events, which you can use to trigger your app to close (using a class like #Pratik does in their answer).
In my opinion, a better solution would be to replace your frame with a JFrame and use it's method f.setDefaultCloseOperation(EXIT_ON_CLOSE) so that you application with exit when the window is closed. JFrame is written such that it should be a drop in replacement for awt.Frame, but is part of the swing toolkit.

How does NetBeans' Splash Screen feature work?

New to NetBeans and just noticed that in the File >> Project Properties >> Application dialog there is a text field labeled Splash Screen that allows you to specify a path to an image that you would like displayed when your program is launching.
I want to customize the way my splash screen works (adding a progress bar, etc.) and would like to code it from the ground up but don't know where to start. What are the best practices for Java/Swing-based splash screens?
Thanks for any and all input!
The project properties -> Application -> Splash Screen allows you to add an image to an application. This property sets a value in the MANIFEST.MF called SplashScreen-Image: e.g. SplashScreen-Image: META-INF/GlassFish316x159.jpg This property will automatically cause the image to display as a splash screen. It does not work inside NetBeans, and must be run outside the IDE.
There is a tutorial Splash Screen Beginner Tutorial that details how to use it more detail. The tutorial was done for NetBeans 6.8, but will work on 7.2.1 which is the latest at the time of this post.
I'm not sure how NetBeans does it, but Splash Screens are supported by the JRE since version 6. See http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javase6/splashscreen/
Splash screen is just a instance of java.awt.Window or undecorated javax.swing.JFrame.
To create window just say new Window(null), then set size and position (using tookit you can calculate where the screen center is) and then say window.setVisible(true)
Due to this is your own window you can do what you want: set layout, image, add process bar to the SOUTH etc.
You can also use JFrame: new JFrame().setUndecorated(true)`
There are a couple of ways to do this.
To do a simple splash screen (an image) you can specify this in the command line of you java application.
Here is a simple example
java -splash:<file name> <class name>
However, if you want a progress bar, you are going to have to do something a little more complicated, and write some code yourself. This is done in the following way.
Create a JWindow (or Window or undecorated JFrame) component with your splash screen elements
Set it to visible
Do the rest of your Swing GUI startup code
Set your JFrame to visible, then immediately follow with setting the JWindow to visible(false)
This should show the splash almost immediately, and then hide once the your application is fully loaded.
To see some splash screen code, take a look here. The implementation in the link only shows how to achieve what you can with the -splash command, but it will give you a good start to also include the progress bar that you requested.
I hope this helps you, it is a small example of how to create yourself a simple splash screen using a dummy Progress Bar:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class SplashScreen extends JWindow
{
private static JProgressBar progressBar = new JProgressBar();
private static SplashScreen execute;
private static int count;
private static Timer timer1;
public SplashScreen()
{
Container container = getContentPane();
container.setLayout(null);
JPanel panel = new JPanel();
panel.setBorder(new javax.swing.border.EtchedBorder());
panel.setBackground(new Color(255,255,255));
panel.setBounds(10,10,348,150);
panel.setLayout(null);
container.add(panel);
JLabel label = new JLabel("Hello World!");
label.setFont(new Font("Verdana",Font.BOLD,14));
label.setBounds(85,25,280,30);
panel.add(label);
progressBar.setMaximum(50);
progressBar.setBounds(55, 180, 250, 15);
container.add(progressBar);
loadProgressBar();
setSize(370,215);
setLocationRelativeTo(null);
setVisible(true);
}
public void loadProgressBar()
{
ActionListener al = new ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
count++;
progressBar.setValue(count);
if (count == 50){
timer1.stop();
execute.setVisible(false);
//load the rest of your application
}
}};
timer1 = new Timer(50, al);
timer1.start();
}
public static void main (String args[]){
execute = new SplashScreen();
}
}
Cheers!
Also consider to build your application on top of the NetBeans Platform (a Swing-based RCP). One of the many benefits: it comes with a customizable splash screen with progress bar.
Sample progress bar:
http://platform.netbeans.org/tutorials/nbm-paintapp.html#wrappingUp
Port a Swing application to the NetBeans Platform:
http://platform.netbeans.org/tutorials/60/nbm-porting-basic.html
Further links:
http://netbeans.org/features/platform/index.html
http://netbeans.org/features/platform/all-docs.html
If your application is build using NetBeans Platform, then here's a tutorial about splash screen customisation: http://wiki.netbeans.org/Splash_Screen_Beginner_Tutorial
There is a sample Javafx equivalent of Splash screen. However this splash screen is basically a java swing applet that is called from javafx to be displayed to the user and simulates more or less eclipse and netbeans splash screen using progress bar and titles for the loaded contents. This is the link.
You must be able to get the code and separate out the splash screen code written in java swings and use it for yourself.
This is a custom java swings splash screen. and hence to center the splash screen it uses the traditional
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension labelSize = l.getPreferredSize();
setLocation(screenSize.width / 2 - (labelSize.width / 2),
screenSize.height / 2 - (labelSize.height / 2));

Trying to bring swing frame to front before taking a screenshot but getting artifacts

I have a part of my app that takes a screenshot of a certain window but before I do so I want to bring the window to the front. This works fine on my Mac machine but when I tested it on in Windows XP on parallels the screenshot always has a grayed out area where the overlapping window was. It seems the screenshot is always taken while the window I want on top is being transferred to the top. I've tried using both:
frame.setVisible(true);
and
frame.setAlwaysOnTop(true);
Does anyone have a reasonable solution for this issue?
If you are trying to take a screenshot of a window w painted by Java, you can just ask it to paint itself on a
BufferedImage bi = new BufferedImage(
w.width, w.height, BufferedImage.TYPE_INT_RGB);
Graphics g = bi.getGraphics();
by calling the windows' paint(g) method. You can then save the BufferedImage to a file. If you are grabbing an external window, then I believe Oscar Reyes has given you all the answers.
You could add a delay the the thread that takes the screenshot.
You could fire the screenshot from the frame when the it has gained focus:
class ScreenshotShooter implements FocusListener {
public void focusGained( FocusEvent e ) {
// smile.....
// you may add a sec of delay here just be be sure.
}
public void focusLost( FocusEvent e ) {}
}
FocusListener focusListener = new ScreenshotShooter();
frame.addFocusListener( focusListener );
frame.setVisible( true ); // should autofire
frame.remoe( focusListener);
You can do both.

Categories

Resources