Sizing a message box in SWT (Eclipse Platform API) - java

I have to display a message box on some action, I am able to do that but the message dialog box appears smaller in size.Is there any way to increase the size of the message box in java?
here is my code:
Display.getDefault().syncExec(new Runnable () {
#Override
public void run() {
// Get active window page
IWorkbench workbench = PlatformUI.getWorkbench();
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
Shell parent = window.getShell();
MessageBox dialog =
new MessageBox(shell,SWT.RESIZE|SWT.ICON_INFORMATION|SWT.OK);
dialog.setText("Project info");
dialog.setMessage("Project info Text will come here");
int returnCode = dialog.open();
System.out.println("returnCode "+ returnCode);
}
});

You can create your own dialog box. Take a look at the examples here. I've copied the relevant code, in case that link stops working:
public class DialogExample extends Dialog {
public DialogExample(Shell parent) {
super(parent);
}
public String open() {
Shell parent = getParent();
Shell dialog = new Shell(parent, SWT.DIALOG_TRIM
| SWT.APPLICATION_MODAL);
dialog.setSize(100, 100);
dialog.setText("Java Source and Support");
dialog.open();
Display display = parent.getDisplay();
while (!dialog.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
return "After Dialog";
}
public static void main(String[] argv) {
new DialogExample(new Shell());
}
}

As far as i know SWT uses the OS system message box so this means you can only change the title/text and icon type.
But you could use JFace which is an extension to SWT and try to use org.eclipse.jface.dialogs.MessageDialog API.

Here's my version: You don't hardcode your dialog size, rather make it variable on the user's screen size.
I've added my personal helper methods below, and demonstrated their usage.
This would be far more flexible than an OS MessageBox, but you're gonna have to add icons manually (oooooor I think you can even override MessageDialog instead of Dialog - your call)
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;
/**
*
* #author stackoverflow.com/users/1774643/ggrec
*
*/
public class CustomMessageBox extends Dialog
{
// ==================== 1. Static Fields ========================
/*
* Default ratio values for big dialogs
*/
private static final double DEFAULT_DIALOG_WIDTH_SCREEN_PERCENTAGE = 0.63;
private static final double DEFAULT_DIALOG_HEIGHT_SCREEN_PERCENTAGE = 0.75;
// ==================== Static Helper Methods ====================
/**
* <pre>
* Very useful for dialogs. Resizes the dialog shell to a size proportional
* to the primary monitor bounds.
*
* <b>1920x1080 monitor && 0.63x0.75 ratios => 1400x800 shell</b>
*
* This means 63% of screen's width, and 75% of screen's height.
*
* The advantage of this method is that the dialog will always be proportional
* to the screen, no matter what the screen size is (e.g. big LG flat TV screen,
* or MacOS display).
* </pre>
*
* #param shell Dialog shell (e.g. the 'newShell' object in configureShell API from Dialog)
* #param widthRatio A percentage of current screen's size (i.e. smaller than 1, bigger than 0)
* #param heightRatio
*/
public static void resizeAndCenterShellOnScreen(final Shell shell, final double widthRatio, final double heightRatio)
{
final Display display = shell.getDisplay();
final Monitor primaryMonitor = display.getPrimaryMonitor();
final Rectangle monitorRect = primaryMonitor.getBounds();
// 1.) Resize the Shell
final int newWidth = (int) Math.floor(monitorRect.width * widthRatio);
final int newHeight = (int) Math.floor(monitorRect.height * heightRatio);
shell.setSize(newWidth, newHeight);
centerShellOnScreen(shell);
}
public static void centerShellOnScreen(final Shell shell)
{
final Rectangle shellBounds = shell.getBounds();
final Display display = shell.getDisplay();
final Monitor primaryMonitor = display.getPrimaryMonitor();
final Rectangle monitorRect = primaryMonitor.getBounds();
final int x = monitorRect.x + (monitorRect.width - shellBounds.width) / 2;
final int y = monitorRect.y + (monitorRect.height - shellBounds.height) / 2;
shell.setLocation(x, y);
}
// ==================== 3. Static Methods ====================
public static void main(final String[] args)
{
new CustomMessageBox().open();
}
// ==================== 4. Constructors ====================
public CustomMessageBox()
{
super(Display.getDefault().getActiveShell());
}
// ==================== 5. Creators ====================
#Override
protected Control createDialogArea(final Composite parent)
{
final Composite dialogArea = (Composite) super.createDialogArea(parent);
final Label label = new Label(dialogArea, SWT.NULL);
label.setText("YOLO");
label.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true));
return dialogArea;
}
#Override
protected void configureShell(final Shell newShell)
{
super.configureShell(newShell);
resizeAndCenterShellOnScreen(newShell, DEFAULT_DIALOG_WIDTH_SCREEN_PERCENTAGE, DEFAULT_DIALOG_HEIGHT_SCREEN_PERCENTAGE);
}
}
Cheers.

Related

Export composite to image independent of the screen resolution

Is there a way in SWT to export a composite to an image which always has the same size/resolution? The problem is that we have a Dashboard which looks always different when opening on screens with different display size/resolution. The question is now can I export the Dashboard to an image wich has a fixed size and always looks the same no matter on which screen size/resolution it has been created?
For the time being we do it like that but as said it depends on the display it has been created on:
Image image = new Image(Display.getCurrent(), this.content.getBounds().width, this.content.getBounds().height);
ImageLoader loader = new ImageLoader();
FileOutputStream fileOutputStream = new FileOutputStream(file);
GC gc = new GC(image);
this.content.print(gc);
gc.dispose();
loader.data = new ImageData[] { image.getImageData() };
loader.save(fileOutputStream, imageFormat);
fileOutputStream.close();
Is there for example some way to create a virtual screen with a certain resolution, which isn't actually displayed and only used for exporting the Dashboard?
Any help or pointers would be appreciated.
In one of my applications I was creating graphs and charts in SWT. The user was able to export these to an image of a size and format that they specified. My solution was to take the GC of the chart composite and redraw it to a new composite off screen, then export the newly drawn composite.
Here's my class which accomplished this:
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Composite;
/**
* The class used for writing an {#link Composite} to an image file
*
* #author David L. Moffett
*
*/
public class CompositeImageWriter
{
/**
* Redraws the composite to the desired size off-screen and then writes that
* composite as an image to the desired location and in the desired format
*
* #param absolutePath
* the absolute path to the desired output file
* #param compositeToDraw
* the composite to be written to file as an image
* #param width
* the desired width in pixels that the composite should be redrawn
* to
* #param height
* the desired height in pixels that the composite should be redrawn
* to
* #param imageType
* an int representing the type of image that should be written
*/
public static void drawComposite(String absolutePath, Composite compositeToDraw, int width,
int height, int imageType)
{
Image image = new Image(compositeToDraw.getDisplay(), width, height);
GC gc = new GC(image);
int originalWidth = compositeToDraw.getBounds().width;
int originalHeight = compositeToDraw.getBounds().height;
compositeToDraw.setSize(width, height);
compositeToDraw.print(gc);
compositeToDraw.setSize(originalWidth, originalHeight);
ImageLoader loader = new ImageLoader();
loader.data = new ImageData[] { image.getImageData() };
loader.save(absolutePath, imageType);
image.dispose();
gc.dispose();
}
}
For your case of wanting to always export at a specific size, just replace the width and height arguments with appropriate constants.
Edit 1
I should add that the int imageType argument is the corresponding SWT modifier (for example: SWT.IMAGE_PNG, SWT.IMAGE_JPEG, SWT.IMAGE_BMP, etc...).
Edit 2
I updated the static reference to dynamically get the display from the compositeToDraw. Further, here's an example I put together which uses the CompositeImageWriter which you may be able to use to debug your issue:
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
public class CompositeToWrite extends Composite
{
private int width, height;
private Label l;
public CompositeToWrite(Composite parent, int style)
{
super(parent, style);
this.setLayout(new GridLayout(1, true));
this.addListener(SWT.Resize, new Listener()
{
#Override
public void handleEvent(Event event)
{
updateText();
}
});
Button b = new Button(this, SWT.NONE);
b.setText("Export as image (500, 500)");
b.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event event)
{
CompositeImageWriter.drawComposite("./img/output.png", CompositeToWrite.this, 500, 500,
SWT.IMAGE_PNG);
}
});
l = new Label(this, SWT.CENTER);
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
gd.verticalAlignment = SWT.CENTER;
l.setLayoutData(gd);
updateText();
}
protected void updateText()
{
width = this.getBounds().width;
height = this.getBounds().height;
l.setText("My label is centered in composite (" + width + ", " + height + ")");
}
}
In the case of this example I create a simple composite that once added to a shell will look something like this:
When I click the button it resizes the composite to 500 x 500 and writes the resized composite to a file. The result is this picture:
I should note that I did notice the composite flicker when the button is clicked, so this may not be happening completely in the background or "off screen" as I initially suggested.

Create a nice-looking listview in Java

I'm new to Java swing and I'm trying to create a list view showing content of a directory. I expect to create a view like following image:
I know how to use JList, but I don't know how to show icons matching with types of files. As you can see, from the image, we can visually differentiate pdf files with text files and others. Should I try to use JList or another UI component?
I have done something similar; here's an example of my output.
I used a custom renderer for the tree; it produces the indentation, icon, and text that you see in one cell of the leftmost column of the display. Here's the source for that:
package spacecheck.ui.renderer;
import java.awt.Component;
import javax.swing.ImageIcon;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import spacecheck.filedata.FileCollection;
import spacecheck.images.TreeIcon;
/**
* renders the name of a collection for the tree display.
* #author rcook
*
*/
public class CollectionNameRenderer extends DefaultTableCellRenderer // which implements JLabel
// implements TableCellRenderer
{
private static final long serialVersionUID = 1L;
#SuppressWarnings({"unused"})
private void say(String msg) { System.out.println(msg); }
private static TreeIcon tIcon = null;
/**
* set the value of the CollectionName for the JTable; includes using
* indent so that the correct icon can be obtained (icons are different widths
* to implement different indent levels).
*/
public void setValue(Object value)
{
FileCollection fc = (FileCollection)value;
boolean expanded = fc.isExpanded();
int level = fc.getDisplayLevel();
// boolean isSelected = table.
ImageIcon icon = tIcon.getIcon(level, expanded);
if (icon != null) { setIcon(icon); }
setText(value.toString());
}
/**
* get the renderer component for a collection name.
*/
public Component getTableCellRendererComponent
(JTable table, Object value, boolean isSelected, boolean hasFocus,
int rowIndex, int colIndex)
{
if (tIcon == null) { tIcon = new TreeIcon(table.getBackground()); }
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, rowIndex, colIndex);
}
}
That class uses another of mine named TreeIcon; it implements the indentation of the folder icon as shown in the picture as well as choosing the icon depending on the expanded/unexpanded state of the folder. Here's that class:
package spacecheck.images;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* represents an icon used in the directory tree; handles 'expanded' and
* 'unexpanded' directories as well as indentation representing different
* levels.
* #author rcook
*
*/
public class TreeIcon
{
public static int UNEXPANDED = 1;
public static int EXPANDED = 2;
#SuppressWarnings({"unused"})
private void say (String msg) { System.out.println(msg); }
private static ImageIcon expandedIcon = null;
private static ImageIcon unexpandedIcon = null;
private static int iconHeight = 0;
private static int iconWidth = 0;
private static ArrayList<ImageIcon> cachedExpandedIcons = new ArrayList<ImageIcon>();
private static ArrayList<ImageIcon> cachedUnexpandedIcons = new ArrayList<ImageIcon>();
static
{
expandedIcon = new ImageIcon(TreeIcon.class.getResource("images/Expanded.png"));
unexpandedIcon = new ImageIcon(TreeIcon.class.getResource("images/Unexpanded.png"));
iconHeight = unexpandedIcon.getIconHeight();
iconWidth = unexpandedIcon.getIconWidth();
}
public TreeIcon(Color givenColor) { }
public static void main(String ... arguments)
{
JFrame frame = new JFrame("icon test");
JLabel label = new JLabel("background test");
label.setBackground(Color.blue);
TreeIcon treeIcon = new TreeIcon(Color.black);
ImageIcon icon = treeIcon.getIcon(2, false);
label.setIcon(icon);
frame.add(label);
frame.pack();
frame.setVisible(true);
}
/**
* return the icon for an expanded or unexpanded level
* #param int level of folder relative to other levels displayed;
* starts at 0 and increases with depth
* #param boolean indicates whether this level is expanded or not.
* #return ImageIcon appropriate for expansion flag and level.
*/
public ImageIcon getIcon(int level, boolean expanded)
{
ImageIcon result = null;
if (level < 0)
{ System.out.println("level is " + level + ", setting to 0");
level = 0;
}
// set our list of icons depending on whether we are expanded.
ArrayList<ImageIcon> cachedIcons = cachedUnexpandedIcons;
if (expanded) { cachedIcons = cachedExpandedIcons; }
// if we already have this icon in our cache, return it.
if (cachedIcons.size() >= (level+1) && cachedIcons.get(level) != null)
{
result = cachedIcons.get(level);
}
else
{
// generate this icon and store it in the cache before returning it.
ImageIcon baseIcon = unexpandedIcon;
if (expanded) { baseIcon = expandedIcon; }
int iconH = iconHeight;
int iconW = iconWidth*(level+1);
BufferedImage bufferedImage = new BufferedImage(iconW,iconH,BufferedImage.TYPE_INT_ARGB);
Graphics g = bufferedImage.getGraphics();
g.drawImage(baseIcon.getImage(), iconWidth*level, 0, null);
result = new ImageIcon(bufferedImage);
// we've created an icon that was not in the cached list;
// the cached list may have a null at this slot, or it may not yet be
// long enough to have this slot. Ensure that we have enough slots
// in the list, and then add this icon.
for (int i=cachedIcons.size(); i<=level; i++)
{
cachedIcons.add(null);
}
// if (cachedIcons.size() < level + 1) { cachedIcons.add(result); }
// else {
cachedIcons.set(level, result);
// }
// say("adding icon, level = " + level + (expanded ? " " : " un") + "expanded, width = " + iconW);
}
return result;
}
}
To choose icons for different kinds of files, you could have your renderer and icon-chooser look at the file extension (or whatever) to determine which icon out of a map to use.
Hope that helps!

Jslider displaying values of array

I' m trying to change the displayed value(selected variable) to what the slider is in line with. The main issue is the worksheet I'm working from specifies this
"The displaySelected method is responsible for displaying just the selected item. Look at it,and work out why it is always element 0 that is displayed – it is something quite simple, and not something complex."
I understand that the change of display requires the variable selected, I've already tried ( g.drawString(names[selected], 200, 150);) but the issue with this is that it only does value 4 of the array and resets to 0 once moved and doesn't, I know that I have to change the value of selected then, I've tried selected = selector.getValue(); but I'm returned with a null error.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
/**
* A simple address database for Practical 5B
* Demonstrates arrays, graphics, selection.
*/
public class Addresses extends JFrame
implements ChangeListener
{
/**
* Frame coordinate constants
*/
private static final int FRAME_X = 200;
private static final int FRAME_Y = 200;
/**
* Frame size constants
*/
private static final int FRAME_WIDTH = 500;
private static final int FRAME_HEIGHT = 400;
/**
* The slider for selecting an address record (selectable 0 to size-1).
*/
private JSlider selector;
/**
* Array to hold the database.
*/
private String[] names;
/**
* To indicate which entry is currently selected.
*/
private int selected;
/**
* The drawing panel for display of information.
*/
private JPanel panel;
/**
* Drawing panel size constants
*/
private final int PANEL_WIDTH = 400;
private final int PANEL_HEIGHT = 300;
/**
* The main program launcher for the Addresses class.
*
* #param args The command line arguments (ignored here).
*/
public static void main( String[] args )
{
Addresses frame = new Addresses();
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setUpData(); // Initial data set-up
frame.createGUI(); // Initial GUI set-up
frame.setVisible( true );
}
/**
* Sets up the graphical user interface.
*/
private void createGUI()
{
setDefaultCloseOperation( EXIT_ON_CLOSE );
Container window = getContentPane();
window.setLayout( new FlowLayout() );
// Slider for selecting an address entry
selector = new JSlider(JSlider.VERTICAL, 0, 0, 0);
// Note: the useable range of the slider is 0 - 0 at the moment!
window.add(selector);
selector.addChangeListener(this);
// Graphics panel for displaying the address list
panel = new JPanel()
{
// paintComponent is called automatically when a screen refresh is needed
public void paintComponent(Graphics g)
{
// g is a cleared panel area
super.paintComponent(g); // Paint the panel's background
paintScreen(g); // Then the required graphics
}
};
panel.setPreferredSize( new Dimension( PANEL_WIDTH, PANEL_HEIGHT ) );
panel.setBackground( Color.white );
window.add( panel );
}
/**
* Helper method to set up the array data, and the associated variable selected,
* with their initial configuration.
*/
private void setUpData()
{
// All the data is "built-in": set it up here - just one entry at the moment
names = new String[6]; // Create the array with space for one entry
names[0] = "James"; // The entry
names[1] = "Connor";
names[2] = "Alfred";
names[3] = "Billy";
names[4] = "Jack";
names[5] = "Chris";
selected = names.length-1; // Indicate that entry 0 is selected
}
/**
* This methods redraws the screen.
*/
private void paintScreen(Graphics g)
{
displayList(g);
displaySelected(g);
}
/**
* Display all the elements of array names in a column on the screen.
*/
private void displayList(Graphics g)
{
int y = 100; // Top y coordinate of the column
g.setColor(Color.black);
/*
g.drawString(names[0], 20, y);
g.drawString(names[1], 20, y+25);
g.drawString(names[2], 20, y+50);
g.drawString(names[3], 20, y+75);
g.drawString(names[4], 20, y+100);
g.drawString(names[5], 20, y+125);
*/
for (int i = 0; i< names.length; i++)
g.drawString(names[i], 20, y+25*i);
}
/**
* Display the single element of array names that is currently selected by the slider.
*/
private void displaySelected(Graphics g)
{
g.setColor(Color.black);
g.drawString("Current selection is:", 200, 135);
g.drawString(names[selected], 200, 150);
}
/**
* Reacts to adjustment of the slider.
* Notes the new selector setting, then forces screen refresh.
*/
public void stateChanged( ChangeEvent e )
{
// selector has been adjusted: record the new setting
selected = selector.getValue();
repaint(); // Refresh the screen
}
}
You never set the maximum value for the slider. That's why you can't move it. Make this change to your code, then you will be able to debug the rest of this program.
selector = new JSlider(JSlider.VERTICAL, 0, names.length-1 /* HERE */ , 0);

Splash Screen Opening Program After Loading

I need some help, I have been looking around on the internet for code, for a splash screen, I have found some code which is perfect, but there is one problem, I would like the splash screen to open my program after it is done loading, how would I go about doing this? Here is the code for my Splash Screen:
/*
* This demonstration program is released without warranty or restrictions.
* You may modify and use it as you wish.
* Just don't complain to me if you have trouble.
*/
package splashdemo;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.SplashScreen;
import java.awt.geom.Rectangle2D;
/**
* Example for Splash Screen tutorial
* #author Joseph Areeda
*/
public class Main
{
static SplashScreen mySplash; // instantiated by JVM we use it to get graphics
static Graphics2D splashGraphics; // graphics context for overlay of the splash image
static Rectangle2D.Double splashTextArea; // area where we draw the text
static Rectangle2D.Double splashProgressArea; // area where we draw the progress bar
static Font font; // used to draw our text
public static void main(String[] args)
{
splashInit(); // initialize splash overlay drawing parameters
appInit(); // simulate what an application would do before starting
if (mySplash != null) // check if we really had a spash screen
mySplash.close(); // we're done with it
// begin with the interactive portion of the program
}
/**
* just a stub to simulate a long initialization task that updates
* the text and progress parts of the status in the Splash
*/
private static void appInit()
{
for (int i = 1; i <= 10; i++)
{ // pretend we have 10 things to do
int pctDone = i * 10; // this is about the only time I could calculate rather than guess progress
splashText("Configuring Program"); // tell the user what initialization task is being done
splashProgress(pctDone); // give them an idea how much we have completed
try
{
Thread.sleep(1000); // wait a second
}
catch (InterruptedException ex)
{
break;
}
}
}
/**
* Prepare the global variables for the other splash functions
*/
private static void splashInit()
{
// the splash screen object is created by the JVM, if it is displaying a splash image
mySplash = SplashScreen.getSplashScreen();
// if there are any problems displaying the splash image
// the call to getSplashScreen will returned null
if (mySplash != null)
{
// get the size of the image now being displayed
Dimension ssDim = mySplash.getSize();
int height = ssDim.height;
int width = ssDim.width;
// stake out some area for our status information
splashTextArea = new Rectangle2D.Double(15., height*0.88, width * .45, 32.);
splashProgressArea = new Rectangle2D.Double(width * .55, height*.92, width*.4, 12 );
// create the Graphics environment for drawing status info
splashGraphics = mySplash.createGraphics();
font = new Font("Dialog", Font.PLAIN, 14);
splashGraphics.setFont(font);
// initialize the status info
splashText("Starting");
splashProgress(0);
}
}
/**
* Display text in status area of Splash. Note: no validation it will fit.
* #param str - text to be displayed
*/
public static void splashText(String str)
{
if (mySplash != null && mySplash.isVisible())
{ // important to check here so no other methods need to know if there
// really is a Splash being displayed
// erase the last status text
splashGraphics.setPaint(Color.LIGHT_GRAY);
splashGraphics.fill(splashTextArea);
// draw the text
splashGraphics.setPaint(Color.BLACK);
splashGraphics.drawString(str, (int)(splashTextArea.getX() + 10),(int)(splashTextArea.getY() + 15));
// make sure it's displayed
mySplash.update();
}
}
/**
* Display a (very) basic progress bar
* #param pct how much of the progress bar to display 0-100
*/
public static void splashProgress(int pct)
{
if (mySplash != null && mySplash.isVisible())
{
// Note: 3 colors are used here to demonstrate steps
// erase the old one
splashGraphics.setPaint(Color.LIGHT_GRAY);
splashGraphics.fill(splashProgressArea);
// draw an outline
splashGraphics.setPaint(Color.BLUE);
splashGraphics.draw(splashProgressArea);
// Calculate the width corresponding to the correct percentage
int x = (int) splashProgressArea.getMinX();
int y = (int) splashProgressArea.getMinY();
int wid = (int) splashProgressArea.getWidth();
int hgt = (int) splashProgressArea.getHeight();
int doneWidth = Math.round(pct*wid/100.f);
doneWidth = Math.max(0, Math.min(doneWidth, wid-1)); // limit 0-width
// fill the done part one pixel smaller than the outline
splashGraphics.setPaint(Color.GREEN);
splashGraphics.fillRect(x, y+1, doneWidth, hgt-1);
// make sure it's displayed
mySplash.update();
}
}
}
call your program on your splash demo main method,
public static void main(String[] args)
{
splashInit();
appInit();
if (mySplash != null)
mySplash.close();
//call your program here, example HelloWorld.java
HelloWorld hello = new Helloworld();
String[] args = {};
hello.main(args);
}

Setting size of inner region of Java SWT shell window

In a Java SWT shell window, how do I set its inner size than its whole window frame size?
For instance, if I use shell.setSize(300, 250) this would make the whole window appearing as exactly 300x250. This 300x250 includes the size of the window frame.
How can I set the inner size, that is the content display region of the shell window to 300x250 instead? That's this 300x250 excludes the width of the window frame.
I tried to minus some offset values but the thing is different Operating Systems have different window frame sizes. So having a constant offset would not be accurate.
Thanks.
From your question what I understood is that you want to set the dimension of the Client Area. And in SWT lingo it is defined as a rectangle which describes the area of the receiver which is capable of displaying data (that is, not covered by the "trimmings").
You cannot directly set the dimension of Client Area because there is no API for it. Although you can achieve this by a little hack. In the below sample code I want my client area to be 300 by 250. To achieve this I have used the shell.addShellListener() event listener. When the shell is completely active (see the public void shellActivated(ShellEvent e)) then I calculate the different margins and again set the size of my shell. The calculation and resetting of the shell size gives me the desired shell size.
>>Code:
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
public class MenuTest {
public static void main (String [] args)
{
Display display = new Display ();
final Shell shell = new Shell (display);
GridLayout layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
layout.horizontalSpacing = 0;
layout.verticalSpacing = 0;
layout.numColumns = 1;
shell.setLayout(layout);
shell.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true,true));
final Menu bar = new Menu (shell, SWT.BAR);
shell.setMenuBar (bar);
shell.addShellListener(new ShellListener() {
public void shellIconified(ShellEvent e) {
}
public void shellDeiconified(ShellEvent e) {
}
public void shellDeactivated(ShellEvent e) {
}
public void shellClosed(ShellEvent e) {
System.out.println("Client Area: " + shell.getClientArea());
}
public void shellActivated(ShellEvent e) {
int frameX = shell.getSize().x - shell.getClientArea().width;
int frameY = shell.getSize().y - shell.getClientArea().height;
shell.setSize(300 + frameX, 250 + frameY);
}
});
shell.open ();
while (!shell.isDisposed()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
}
If I get you right you should set the size of the inner component to the needed size and use the method pack() (of the frame).
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
public class SWTClientAreaTest
{
Display display;
Shell shell;
final int DESIRED_CLIENT_AREA_WIDTH = 300;
final int DESIRED_CLIENT_AREA_HEIGHT = 200;
void render()
{
display = Display.getDefault();
shell = new Shell(display, SWT.SHELL_TRIM | SWT.CENTER);
Point shell_size = shell.getSize();
Rectangle client_area = shell.getClientArea();
shell.setSize
(
DESIRED_CLIENT_AREA_WIDTH + shell_size.x - client_area.width,
DESIRED_CLIENT_AREA_HEIGHT + shell_size.y - client_area.height
);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
}
}
display.dispose();
}
public static void main(String[] args)
{
SWTClientAreaTest appl = new SWTClientAreaTest();
appl.render();
}
}
Use computeTrim to calculate the bounds that are necessary to display a given client area. The method returns a rectangle that describes the bounds that are needed to provide room for the client area specified in the arguments.
In this example the size of the shell is set so that it is capable to display a client area of 100 x 200 (width x height):
Rectangle bounds = shell.computeTrim(0, 0, 100, 200);
shell.setSize(bounds.width, bounds.height);
This article describes the terms used by SWT for widget dimensions:
https://www.eclipse.org/articles/Article-Understanding-Layouts/Understanding-Layouts.htm

Categories