WearableRecyclerView scrolls not curved - android-recyclerview

My WearableRecyclerView the lines go like a triangle and not really curved like the homescreen of the watch. I can't find any mistakes in my code.
ShareActivity:
private void initListView() {
WearableRecyclerView recyclerView = findViewById(R.id.lVDevices);
recyclerView.setEdgeItemsCenteringEnabled(true);
final ScrollingLayoutCallback scrollingLayoutCallback =
new ScrollingLayoutCallback();
adapter = new ShareAdapter(new ShareAdapter.Callback() {
#Override
public void onDeviceClicked(int position, String deviceName) {
onListItemClick(position, deviceName);
}
});
recyclerView.setLayoutManager(
new WearableLinearLayoutManager(this, scrollingLayoutCallback));
recyclerView.setAdapter(adapter);
}
ScrollingLayoutCallback:
public class ScrollingLayoutCallback extends WearableLinearLayoutManager.LayoutCallback {
private static final float MAX_ICON_PROGRESS = 0.65f;
#Override
public void onLayoutFinished(View child, RecyclerView parent) {
// Figure out % progress from top to bottom
float centerOffset = ((float) child.getHeight() / 2.0f) / (float) parent.getHeight();
float yRelativeToCenterOffset = (child.getY() / parent.getHeight()) + centerOffset;
// Normalize for center
float mProgressToCenter = Math.abs(0.5f - yRelativeToCenterOffset);
// Adjust to the maximum scale
mProgressToCenter = Math.min(mProgressToCenter, MAX_ICON_PROGRESS);
child.setScaleX(1 - mProgressToCenter);
child.setScaleY(1 - mProgressToCenter);
}
}
ListView-XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/refreshlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent">
<android.support.wear.widget.WearableRecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lVDevices"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:scrollbars="vertical"/>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
XML of the row
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/lVDevices_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:drawableStart="#drawable/point_img"
android:layout_centerHorizontal="true"
android:textSize="18sp">
</TextView>
Is the problem in the Callback method? I mean is there a mistake in the calculation because it is from the developer website.
Edit 1: New Math in ScrollingCallback class
float centerOffset = ((float) child.getHeight() / 2.0f) / (float) parent.getHeight();
float yRelativeToCenterOffset = (child.getY() / parent.getHeight()) + centerOffset;
float progresstoCenter = (float) Math.sin(yRelativeToCenterOffset * Math.PI);
child.setScaleX(progresstoCenter);
child.setScaleY(progresstoCenter);

I've created a solution.
Like the OP, I never liked the solution given in the official Android documentation, which causes the list elements to move along a triangular path (straight line from the top center to the middle left, and then straight line from there to the bottom center).
The solution is simple, using trig to change the path to semi-circular. Replace the CustomScrollingLayoutCallback with this:
class CustomScrollingLayoutCallback extends WearableLinearLayoutManager.LayoutCallback {
#Override
public void onLayoutFinished(View child, RecyclerView parent) {
final float MAX_ICON_PROGRESS = 0.65f;
try {
float centerOffset = ((float) child.getHeight() / 2.0f) / (float) parent.getHeight();
float yRelativeToCenterOffset = (child.getY() / parent.getHeight()) + centerOffset;
// Normalize for center, adjusting to the maximum scale
float progressToCenter = Math.min(Math.abs(0.5f - yRelativeToCenterOffset), MAX_ICON_PROGRESS);
// Follow a curved path, rather than triangular!
progressToCenter = (float)(Math.cos(progressToCenter * Math.PI * 0.70f));
child.setScaleX (progressToCenter);
child.setScaleY (progressToCenter);
} catch (Exception ignored) {}
}
}
The "... * 0.70f" on that 4th-to-last line was determined by trial-and-error, and alters the curve to best match the official Android Wear curve.

Related

set camera Preview Aspect ratio manually with current display metrics

I tried to develop camera preview UI with selected specific aspect ratios. But I couldn't get the correct resolution based on the selected ratio. I have 9:16(full screen), 16:9, 2.35:1 and 1:1 ratio options portrait mode. My XML like below:
<FrameLayout ..>
<RelativeLayout
android:id="#+id/cameraContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?actionBarSize">
<LinearLayout
android:id="#+id/cameraPreview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"/>
</RelativeLayout>
</FrameLayout>
I tried to change cameraContainer width and height change and then I expect to same changing to camera. But It could not happen. My kotlin code is below:
fun setRatio(selectedRatioId:Int){
when(selectedRatioId){
1->{
//9:16
cameraContainerParams.height = gettingDisplayMetrics.height
}
2->{
//16:9
cameraContainerParams.height = (gettingDisplayMetrics.width*9) /16
}
3->{
//1:1
cameraContainerParams.height = gettingDisplayMetrics.width
}
3->{
//2.35:1
cameraContainerParams.height = ((gettingDisplayMetrics.width) / 2.35).toInt()
}
}
cameraContainerParams.width = gettingDisplayMetrics.width
cameraContainer.layoutParams = cameraContainerParams
}
result is(p40 lite):
9:16 is output 1080x2090 but camera output 992x 1920
16:9 is output 1080x 607 (expected 1080 x 608)
1:1 is output 480 x 480 (I expect 1080 x 1080)
2.35:1 is output 1080 x 459( expected 1080 x 460)
how can I set the correct aspect value camera with the selection?

Can I use a QPainter to draw a line with a per-vertex color?

I have a custom Qt 5 widget that renders itself using QPainter. I would like to be able to draw a line where each vertex is associated with a different color, and the color is interpolated accordingly along the lines joining the points. Is this possible?
I think you'll need to perform the drawing on a line-by-line basis. Assuming that's acceptable then a QPen initialized with a suitable QLinearGradient should work...
class widget: public QWidget {
using super = QWidget;
public:
explicit widget (QWidget *parent = nullptr)
: super(parent)
{
}
protected:
virtual void paintEvent (QPaintEvent *event) override
{
super::paintEvent(event);
QPainter painter(this);
/*
* Define the corners of a rectangle lying 10 pixels inside
* the current bounding rect.
*/
int left = 10, right = width() - 10;
int top = 10, bottom = height() - 10;
QPoint top_left(left, top);
QPoint top_right(right, top);
QPoint bottom_right(right, bottom);
QPoint bottom_left(left, bottom);
/*
* Insert the points along with their required colours into
* a suitable container.
*/
QVector<QPair<QPoint, QColor>> points;
points << qMakePair(top_left, Qt::red);
points << qMakePair(top_right, Qt::green);
points << qMakePair(bottom_right, Qt::blue);
points << qMakePair(bottom_left, Qt::black);
for (int i = 0; i < points.size(); ++i) {
int e = (i + 1) % points.size();
/*
* Create a suitable linear gradient based on the colours
* required for vertices indexed by i and e.
*/
QLinearGradient gradient;
gradient.setColorAt(0, points[i].second);
gradient.setColorAt(1, points[e].second);
gradient.setStart(points[i].first);
gradient.setFinalStop(points[e].first);
/*
* Set the pen and draw the line.
*/
painter.setPen(QPen(QBrush(gradient), 10.0f));
painter.drawLine(points[i].first, points[e].first);
}
}
};
The above results in something like...
(Note: There may be a better way to achieve this using QPainterPath and QPainterPathStroker but I'm not sure based on the docs. I've looked at.)

Windows UWP Extended splash screen image rendering incorrectly on mobile

I built an extended splash screen for my windows uwp application. I followed the example code including the xaml for extended spash screen from this page
Display a splash screen for more time
It renders correctly on the desktop window, it is centered perfectly and aligned exactly with the initial splash screen image, however when I try a mobile emulator, (I tried one of 5 inch screen at 720p) the extended splash screen page image seems too large (it looks almost twice or three times larger), and appears cut off to the bottom right of the page, I'm assuming the progress ring is below the image and is beyond the page boundary so it is not visible.
Here is what it looks like on mobile, left image is the initial splash screen, and the one on the right is the extended splash page.
My XAMLfor the extended splash page is like this
<Page
x:Class="MyApp_Win10.ExtendedSplash"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyApp_Win10"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="#FF000012" >
<Canvas>
<Image x:Name="extendedSplashImage" Source="Assets/SplashScreen/SplashScreenImage3.png"/>
<ProgressRing Name="splashProgressRing" IsActive="True" Width="60" Height="60" HorizontalAlignment="Center"></ProgressRing>
</Canvas>
</Grid>
</Page>
And my package.appmanifest looks like this. (There is one image in the Assets forlder that was created as SplashScreenImage3.scale-200.png with dimensions 1240 w x 600 h)
EDIT: I added the remaining 3 image scales 150, 125, and 100 to the package.appmanifest but it made no difference. Since the extended splash page is not the same as the initial splash page, I think it is choosing the exact image file I write in the XAML - which is the full sized on of dimension 1240 w x 600 h.
Also in the codebehind for the extended splash, these are the coordinates of the splash screen
EDIT: My PositionImage() and PositionRing() functions
void PositionImage()
{
extendedSplashImage.SetValue(Canvas.LeftProperty, splashImageRect.X);
extendedSplashImage.SetValue(Canvas.TopProperty, splashImageRect.Y);
extendedSplashImage.Height = splashImageRect.Height;
extendedSplashImage.Width = splashImageRect.Width;
}
void PositionRing()
{
splashProgressRing.SetValue(Canvas.LeftProperty, splashImageRect.X + (splashImageRect.Width * 0.5) - (splashProgressRing.Width * 0.5));
splashProgressRing.SetValue(Canvas.TopProperty, (splashImageRect.Y + splashImageRect.Height + splashImageRect.Height * 0.1));
}
Make sure in your PositionImage() and PositionRing() functions that you handle the case when the device is a phone as follows
void PositionImage()
{
extendedSplashImage.SetValue(Canvas.LeftProperty, splashImageRect.X);
extendedSplashImage.SetValue(Canvas.TopProperty, splashImageRect.Y);
if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
{
extendedSplashImage.Height = splashImageRect.Height / ScaleFactor;
extendedSplashImage.Width = splashImageRect.Width / ScaleFactor;
}
else
{
extendedSplashImage.Height = splashImageRect.Height;
extendedSplashImage.Width = splashImageRect.Width;
}
}
void PositionRing()
{
splashProgressRing.SetValue(Canvas.LeftProperty, splashImageRect.X + (splashImageRect.Width * 0.5) - (splashProgressRing.Width * 0.5));
splashProgressRing.SetValue(Canvas.TopProperty, (splashImageRect.Y + splashImageRect.Height + splashImageRect.Height * 0.1));
if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
{
splashProgressRing.Height = splashProgressRing.Height / ScaleFactor;
splashProgressRing.Width = splashProgressRing.Width / ScaleFactor;
}
}
and
//Variable to hold the device scale factor (use to determine phone screen resolution)
private double ScaleFactor = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
Why haven't you set another scale dimensions?
Just add them and try again.
Looks that your phone isn't has Scale 200
I have the same problem.
In fact the height and width of the splashscreen returned are wrong on the mobile. It return the size of the screen instead!!!! see picture above ( height=1280 width=720, when the actual splashscreen have a width bigger than the height.
I tried to recalculate the splashscreen size by using the width of the screen and guessing the size of the splashscreen used and dividing it by the scle factor, but there is a small difference of size due to a marging or something....
It would be great if someone know a better way to calculate the correct size instead of kind of guessing....
if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
{
ScaleFactor = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
double screenwidth = _splashImageRect.Width;
if (screenwidth <= 1240)
{
// small screen will use the splashscreen scale 100 - 620x300
ExtendedSplashImage.Height = 300 / ScaleFactor;
ExtendedSplashImage.Width = 620 / ScaleFactor;
}
else if (screenwidth > 1240 && screenwidth <= 2480)
{
// medium screen will use the splashscreen scale 200 - 1240x600
ExtendedSplashImage.Height = (600 / ScaleFactor);
ExtendedSplashImage.Width = (1240 / ScaleFactor);
}
else if (screenwidth > 2480)
{
// big screen will use the splashscreen scale 400 - 2480x1200
ExtendedSplashImage.Height = 1200 / ScaleFactor;
ExtendedSplashImage.Width = 2480 / ScaleFactor;
}
}
else
{
ExtendedSplashImage.Height = splashImageRect.Height;
ExtendedSplashImage.Width = splashImageRect.Width;
}
I have found the solution for the mobile and if you try to share your app with another app:
private void PositionImage()
{
if(Windows.Foundation.Metadata.ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
{
double screenWidth = _splashImageRect.Width;
ExtendedSplashImage.Width = screenWidth/ ScaleFactor;
// use the ratio of your splashscreen to calculate the height
ExtendedSplashImage.Height = ((screenWidth / ScaleFactor) * 600) / 1240;
}
else
{
// if the app is shared with another app the _splashImageRect is not returns properly too
if (_splashImageRect.Width > windowContext.VisibleBounds.Width || _splashImageRect.Width < 1)
{
ExtendedSplashImage.Width = windowContext.VisibleBounds.Width;
// use the ratio of your splashscreen to calculate the height
ExtendedSplashImage.Height = ((windowContext.VisibleBounds.Width) * 600) / 1240;
}
else
{
ExtendedSplashImage.Height = _splashImageRect.Height;
ExtendedSplashImage.Width = _splashImageRect.Width;
}
}
Double left = windowContext.VisibleBounds.Width / 2 - ExtendedSplashImage.ActualWidth / 2;
Double top = windowContext.VisibleBounds.Height / 2 - ExtendedSplashImage.ActualHeight / 2;
ExtendedSplashImage.SetValue(Canvas.LeftProperty, left);
ExtendedSplashImage.SetValue(Canvas.TopProperty, top);
ProgressRing.SetValue(Canvas.LeftProperty, left + ExtendedSplashImage.ActualWidth / 2 - ProgressRing.Width / 2);
ProgressRing.SetValue(Canvas.TopProperty, top + ExtendedSplashImage.ActualHeight);
}

Objective-C class unable to respond to helper method

I am receiving the familiar and nonspecific diagnostic: "No visible #interface for... declares the selector ..." I appreciate that this diagnostic has appeared numerous times on this site (I have looked at most of them), but none of the suggested fixes seem to be relevant to my case. Thanks!
I have an old Cocoa program which rotates an OpenGL surface using the mouse. (It is based upon an old Apple demo: NSGL Teapot). The surface is created in an NSOpenGLView (Class SurfaceView) and the code used to perform the rotation is in a helper class called Trackball. When the mouse "slides" on the screen, a method (called rollTo) in a Trackball instance invokes a method (called rotateBy) in SurfaceView which provides the amount of rotation. Unfortunately, Xcode 7.3 complains that NSOpenGLView lacks a visible interface for the rotateBy selector (method).
The code compiled perfectly 15 years ago, but not now. Everything else in the program works fine (i.e., the surface is rendered and it responds correctly to various sliders, etc.) Can you suggest how I can get the OpenGL view to respond to rotateBy?
Thanks very much!
Here is the Interface (indented 4 spaces)
#import <Cocoa/Cocoa.h>
#import <OpenGL/OpenGL.h>
#import <OpenGL/gl.h>
#import <OpenGL/glu.h>
#import <GLUT/glut.h>
#import "Trackball.h"
#interface SurfaceView : NSOpenGLView
{
float width;
GLUnurbsObj *theNurb;
Trackball *m_trackball;
// The main rotation
float m_rotation[4];
// The trackball rotation
float m_tbRot[4];
}
- (id)initWithFrame:(NSRect)frameRect;
- (void)drawRect:(NSRect)rect;
- (void)rotateBy:(float *)r;
- (void)mouseDown:(NSEvent *)theEvent;
- (void)mouseUp:(NSEvent *)theEvent;
- (void)mouseDragged:(NSEvent *)theEvent;
- (void)zeroRotate;
#end
Method body:
- (void)rotateBy:(float *)r
{
m_tbRot[0] = r[0];
m_tbRot[1] = r[1];
m_tbRot[2] = r[2];
m_tbRot[3]= r[3];
}
Here is the method in which the error occurs:
- (void)rollTo:(NSPoint)pt sender:(NSOpenGLView *)sender
{
float xxyy;
float rot[4];
float cosAng, sinAng;
float ls, le, lr;
m_endPt[0] = pt.x - m_ctr.x;
m_endPt[1] = pt.y - m_ctr.y;
if (fabs(m_endPt[0] - m_startPt[0]) < kTol && fabs(m_endPt[1] - m_startPt[1]) < kTol)
return; // Not enough change in the vectors to have an action.
// Compute the ending vector from the surface of the ball to its center.
xxyy = m_endPt[0]*m_endPt[0] + m_endPt[1]*m_endPt[1];
if (xxyy > m_radius*m_radius) {
// Outside the sphere.
m_endPt[2] = 0.;
} else
m_endPt[2] = sqrt(m_radius*m_radius - xxyy);
// Take the cross product of the two vectors. r = s X e
rot[1] = m_startPt[1] * m_endPt[2] - m_startPt[2] * m_endPt[1];
rot[2] = -m_startPt[0] * m_endPt[2] + m_startPt[2] * m_endPt[0];
rot[3] = m_startPt[0] * m_endPt[1] - m_startPt[1] * m_endPt[0];
// Use atan for a better angle. If you use only cos or sin, you only get
// half the possible angles, and you can end up with rotations that flip around near
// the poles.
// cos(a) = (s . e) / (||s|| ||e||)
cosAng = m_startPt[0]*m_endPt[0] + m_startPt[1]*m_endPt[1] + m_startPt[2]*m_endPt[2]; // (s . e)
ls = sqrt(m_startPt[0]*m_startPt[0] + m_startPt[1]*m_startPt[1] + m_startPt[2]*m_startPt[2]);
ls = 1. / ls; // 1 / ||s||
le = sqrt(m_endPt[0]*m_endPt[0] + m_endPt[1]*m_endPt[1] + m_endPt[2]*m_endPt[2]);
le = 1. / le; // 1 / ||e||
cosAng = cosAng * ls * le;
// sin(a) = ||(s X e)|| / (||s|| ||e||)
sinAng = lr = sqrt(rot[1]*rot[1] + rot[2]*rot[2] + rot[3]*rot[3]); // ||(s X e)||;
// keep this length in lr for normalizing the rotation vector later.
sinAng = sinAng * ls * le;
rot[0] = (float)atan2(sinAng, cosAng) * kRad2Deg; // GL rotations are in degrees.
// Normalize the rotation axis.
lr = 1. / lr;
rot[1] *= lr; rot[2] *= lr; rot[3] *= lr;
[sender rotateBy:rot];
}
If you want to call rotateBy: on sender then your method signature needs to have a sender that implements that method.
Rewrite it as:
- (void)rollTo:(NSPoint)pt sender:(SurfaceView *)sender
You could also use a cast on sender but that's more dangerous. (i.e. likely to get a run-time error instead of a compiler one.)
The usage is wrong. It was probably always wrong, only the compiler is now detecting it better.
Your sender is declared as NSOpenGLView and you are calling rotateBy: method on it. NSOpenGLView does not have any such method. It's the subclass SurfaceView that has the method.
One simple fix is to declare sender as id, to completely remove type information.
A better fix is to declare the sender parameter correctly as SurfaceView.
If you need to keep the same interface, just perform a cast
[(SurfaceView *) sender rotateBy:rot];

SWT Canvas Location

I'm using the most recent stable version of SWT.
I have a Shell containing a ToolBar, a ScrolledComposite, and a Canvas. The Canvas is set as the ScrolledComposite's content (e.g. scrolledComposite.setContent(canvas)). The Canvas is created with a specific size that never changes (say, 400 x 400). Whereas the ScrolledComposite is constantly growing or shrinking to fill the available parent shell's client area.
I have a resize listener attached to the parent Shell that attempts to do the following: a) grow the ScrolledComposite as described above and b) center the Canvas both horizontally and vertically within the ScrolledComposite (see below for example code).
This works exactly as it should on Mac OS X, however on Windows the resize event is fired and the new locations are properly calculated but ultimately the Canvas snaps back to 0,0. One other small piece of information is that if you continuously resize the window, you can see the canvas flickering and it looks as if it's being briefly drawn at the correct location.
_shell.addListener (SWT.Resize, new Listener () {
public void handleEvent (Event e)
{
int toolBarOffset = _toolBar.getSize().y;
Rectangle clientArea = _shell.getClientArea();
_scrollComposite.setBounds(0, toolBarOffset, clientArea.width, clientArea.height - toolBarOffset);
Point canvasSize = _canvas.getSize();
int canvasX = Math.max(0, (clientArea.width / 2) - (canvasSize.x / 2));
int canvasY = Math.max(0, ((clientArea.height - toolBarOffset) / 2) - (canvasSize.y / 2));
_canvas.setLocation(canvasX, canvasY);
}
});
Not sure if you've already figured it out, but the problem is that the ScrolledComposite always sets the content to 0/0 when it is resized. I'm not sure why your approach works on OS X, and I've not tested my example as I don't have a Mac here.
The solution is to use a filler composite that is always at least as big as the client area from the ScrolledComposite. In that filler, you can then center the Canvas correctly.
I've made a small example, as an added bonus it also centers the canvas if the client area of the SC is smaller than the canvas ( because I've first thought that was your question :) )
You may have to make some minor adjustments, I guess there are some glitches on OS X with that code...
package test;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class Test {
public static void main(final String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout( new FillLayout() );
final ScrolledComposite sComp = new ScrolledComposite( shell, SWT.H_SCROLL | SWT.V_SCROLL );
final Composite fillComp = new Composite( sComp, SWT.NONE );
sComp.setLayout( new FillLayout() );
final Canvas c = new Canvas( fillComp, SWT.DOUBLE_BUFFERED );
c.addPaintListener( new PaintListener() {
public void paintControl(PaintEvent e) {
Point p = c.getSize();
e.gc.setBackground( display.getSystemColor( SWT.COLOR_RED ));
e.gc.fillRectangle( 0, 0, p.x, p.y );
e.gc.setBackground( display.getSystemColor( SWT.COLOR_BLUE ));
e.gc.fillRectangle( p.x / 2 - 10, p.y / 2 - 10, 20, 20 );
}
});
c.setSize( 400, 400 );
sComp.setContent( fillComp );
sComp.addControlListener( new ControlAdapter() {
#Override
public void controlResized(ControlEvent e) {
Rectangle clientArea = sComp.getClientArea();
Point cSize = c.getSize();
int fillX = Math.max( clientArea.width, cSize.x );
int fillY = Math.max( clientArea.height, cSize.y );
fillComp.setSize( fillX, fillY );
int cX = ( clientArea.width - cSize.x ) / 2;
int cY = ( clientArea.height - cSize.y ) / 2;
sComp.setOrigin( -cX, -cY );
int locX = Math.max( cX, 0 );
int locY = Math.max( cY, 0 );
c.setLocation( locX, locY );
}
});
shell.open();
shell.pack();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
}